1 module gfx.gl3.swapchain;
2 
3 import gfx.graal.presentation : Surface, Swapchain;
4 
5 final class GlSurface : Surface
6 {
7     import gfx.core.rc : atomicRcCode;
8 
9     mixin(atomicRcCode);
10 
11     private size_t _handle;
12 
13     this(size_t handle) {
14         _handle = handle;
15     }
16     override void dispose() {}
17 
18     @property size_t handle() {
19         return _handle;
20     }
21 }
22 
23 package final class GlSwapchain : Swapchain
24 {
25     import core.time : Duration;
26     import gfx.core.rc : atomicRcCode, Rc;
27     import gfx.gl3 : GlShare;
28     import gfx.gl3.device : GlDevice;
29     import gfx.gl3.resource : GlImage;
30     import gfx.graal.format : Format;
31     import gfx.graal.image : ImageBase, ImageInfo, ImageUsage;
32     import gfx.graal.presentation : CompositeAlpha, PresentMode;
33     import gfx.graal.sync : Semaphore;
34 
35     mixin(atomicRcCode);
36 
37     Rc!GlShare _share;
38     GlSurface _surface;
39     GlImage[] _imgs;
40     ImageBase[] _imgsB; // same objects, but already cast to interface (points to different addresses)
41     uint[2] _size;
42     Format _format;
43     uint _nextImg;
44 
45 
46     this (GlShare share, GlDevice device, Surface surface, PresentMode pm, uint numImages,
47           Format format, uint[2] size, ImageUsage usage, CompositeAlpha alpha,
48           Swapchain former=null)
49     {
50         _share = share;
51         _surface = cast(GlSurface)surface;
52         _format = format;
53         _size = size;
54 
55         _imgs = new GlImage[numImages];
56         _imgsB = new ImageBase[numImages];
57         auto mem = device.allocateMemory(0, 1); // dummy memory
58         mem.retain();
59         foreach (i; 0 .. numImages) {
60             auto img = new GlImage(
61                 _share, ImageInfo.d2(size[0], size[1]).withFormat(format).withUsage(usage)
62             );
63             img.bindMemory(mem, 0);
64 
65             _imgs[i] = img;
66             _imgsB[i] = cast(ImageBase)img;
67         }
68         mem.release();
69 
70         import gfx.core.rc : retainArray;
71         retainArray(_imgs);
72     }
73 
74     override void dispose() {
75         import gfx.core.rc : releaseArray;
76         releaseArray(_imgs);
77         _share.unload();
78     }
79 
80     override @property Format format() {
81         return _format;
82     }
83 
84     override @property ImageBase[] images() {
85         return _imgsB;
86     }
87 
88     override uint acquireNextImage(Duration timeout, Semaphore semaphore,
89                                    out bool suboptimal) {
90         const ni = _nextImg++;
91         if (_nextImg >= _imgs.length) _nextImg = 0;
92         return ni;
93     }
94 
95     @property GlSurface surface() {
96         return _surface;
97     }
98 
99     @property uint[2] size() {
100         return _size;
101     }
102 }