aboutsummaryrefslogtreecommitdiff
path: root/vendor/gioui.org/app/internal/window/d3d11_windows.go
blob: f1e06a6ea43d16b1d1dc26488dff3fd37bacba74 (plain)
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
}