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