1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
// SPDX-License-Identifier: Unlicense OR MIT
package window
import (
"gioui.org/app/internal/d3d11"
"gioui.org/gpu/backend"
)
type d3d11Context struct {
win *window
swchain *d3d11.SwapChain
fbo *d3d11.Framebuffer
backend backend.Device
*d3d11.Device
width, height int
}
func init() {
backends = append(backends, gpuAPI{
priority: 1,
initializer: func(w *window) (Context, error) {
hwnd, _, _ := w.HWND()
dev, err := d3d11.NewDevice()
if err != nil {
return nil, err
}
swchain, err := dev.CreateSwapChain(hwnd)
if err != nil {
dev.Release()
return nil, err
}
return &d3d11Context{win: w, Device: dev, swchain: swchain}, nil
},
})
}
func (c *d3d11Context) Backend() (backend.Device, error) {
backend, err := d3d11.NewBackend(c.Device)
if err != nil {
return nil, err
}
c.backend = backend
c.backend.BindFramebuffer(c.fbo)
return backend, nil
}
func (c *d3d11Context) Present() error {
if err := c.swchain.Present(); err != nil {
if err, ok := err.(d3d11.ErrorCode); ok {
switch err.Code {
case d3d11.DXGI_STATUS_OCCLUDED:
// Ignore
return nil
case d3d11.DXGI_ERROR_DEVICE_RESET, d3d11.DXGI_ERROR_DEVICE_REMOVED, d3d11.D3DDDIERR_DEVICEREMOVED:
return ErrDeviceLost
}
}
}
return nil
}
func (c *d3d11Context) MakeCurrent() error {
_, width, height := c.win.HWND()
if c.fbo != nil && width == c.width && height == c.height {
c.backend.BindFramebuffer(c.fbo)
return nil
}
if c.fbo != nil {
c.fbo.Release()
c.fbo = nil
}
if err := c.swchain.Resize(); err != nil {
return err
}
c.width = width
c.height = height
fbo, err := c.swchain.Framebuffer(c.Device)
if err != nil {
return err
}
c.fbo = fbo
if c.backend != nil {
c.backend.BindFramebuffer(c.fbo)
}
return nil
}
func (c *d3d11Context) Lock() {}
func (c *d3d11Context) Unlock() {}
func (c *d3d11Context) Release() {
if c.fbo != nil {
c.fbo.Release()
}
c.swchain.Release()
c.Device.Release()
c.fbo = nil
c.swchain = nil
c.Device = nil
}
|