1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // SurfaceD3D.cpp: D3D implementation of an EGL surface
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/SurfaceD3D.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Surface.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/Format.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/DisplayD3D.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/RendererD3D.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/SwapChainD3D.h"
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker #include <EGL/eglext.h>
21*8975f5c5SAndroid Build Coastguard Worker #include <tchar.h>
22*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker namespace rx
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker
SurfaceD3D(const egl::SurfaceState & state,RendererD3D * renderer,egl::Display * display,EGLNativeWindowType window,EGLenum buftype,EGLClientBuffer clientBuffer,const egl::AttributeMap & attribs)27*8975f5c5SAndroid Build Coastguard Worker SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
28*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
29*8975f5c5SAndroid Build Coastguard Worker egl::Display *display,
30*8975f5c5SAndroid Build Coastguard Worker EGLNativeWindowType window,
31*8975f5c5SAndroid Build Coastguard Worker EGLenum buftype,
32*8975f5c5SAndroid Build Coastguard Worker EGLClientBuffer clientBuffer,
33*8975f5c5SAndroid Build Coastguard Worker const egl::AttributeMap &attribs)
34*8975f5c5SAndroid Build Coastguard Worker : SurfaceImpl(state),
35*8975f5c5SAndroid Build Coastguard Worker mRenderer(renderer),
36*8975f5c5SAndroid Build Coastguard Worker mDisplay(display),
37*8975f5c5SAndroid Build Coastguard Worker mFixedSize(window == nullptr || attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE),
38*8975f5c5SAndroid Build Coastguard Worker mFixedWidth(0),
39*8975f5c5SAndroid Build Coastguard Worker mFixedHeight(0),
40*8975f5c5SAndroid Build Coastguard Worker mOrientation(static_cast<EGLint>(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0))),
41*8975f5c5SAndroid Build Coastguard Worker mRenderTargetFormat(state.config->renderTargetFormat),
42*8975f5c5SAndroid Build Coastguard Worker mDepthStencilFormat(state.config->depthStencilFormat),
43*8975f5c5SAndroid Build Coastguard Worker mColorFormat(nullptr),
44*8975f5c5SAndroid Build Coastguard Worker mSwapChain(nullptr),
45*8975f5c5SAndroid Build Coastguard Worker mSwapIntervalDirty(true),
46*8975f5c5SAndroid Build Coastguard Worker mNativeWindow(renderer->createNativeWindow(window, state.config, attribs)),
47*8975f5c5SAndroid Build Coastguard Worker mWidth(static_cast<EGLint>(attribs.get(EGL_WIDTH, 0))),
48*8975f5c5SAndroid Build Coastguard Worker mHeight(static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0))),
49*8975f5c5SAndroid Build Coastguard Worker mSwapInterval(1),
50*8975f5c5SAndroid Build Coastguard Worker mShareHandle(0),
51*8975f5c5SAndroid Build Coastguard Worker mD3DTexture(nullptr),
52*8975f5c5SAndroid Build Coastguard Worker mBuftype(buftype)
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker if (window != nullptr && !mFixedSize)
55*8975f5c5SAndroid Build Coastguard Worker {
56*8975f5c5SAndroid Build Coastguard Worker mWidth = -1;
57*8975f5c5SAndroid Build Coastguard Worker mHeight = -1;
58*8975f5c5SAndroid Build Coastguard Worker }
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker if (mFixedSize)
61*8975f5c5SAndroid Build Coastguard Worker {
62*8975f5c5SAndroid Build Coastguard Worker mFixedWidth = mWidth;
63*8975f5c5SAndroid Build Coastguard Worker mFixedHeight = mHeight;
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker switch (buftype)
67*8975f5c5SAndroid Build Coastguard Worker {
68*8975f5c5SAndroid Build Coastguard Worker case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
69*8975f5c5SAndroid Build Coastguard Worker mShareHandle = static_cast<HANDLE>(clientBuffer);
70*8975f5c5SAndroid Build Coastguard Worker break;
71*8975f5c5SAndroid Build Coastguard Worker
72*8975f5c5SAndroid Build Coastguard Worker case EGL_D3D_TEXTURE_ANGLE:
73*8975f5c5SAndroid Build Coastguard Worker mD3DTexture = static_cast<IUnknown *>(clientBuffer);
74*8975f5c5SAndroid Build Coastguard Worker ASSERT(mD3DTexture != nullptr);
75*8975f5c5SAndroid Build Coastguard Worker mD3DTexture->AddRef();
76*8975f5c5SAndroid Build Coastguard Worker break;
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker default:
79*8975f5c5SAndroid Build Coastguard Worker break;
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker }
82*8975f5c5SAndroid Build Coastguard Worker
~SurfaceD3D()83*8975f5c5SAndroid Build Coastguard Worker SurfaceD3D::~SurfaceD3D()
84*8975f5c5SAndroid Build Coastguard Worker {
85*8975f5c5SAndroid Build Coastguard Worker releaseSwapChain();
86*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mNativeWindow);
87*8975f5c5SAndroid Build Coastguard Worker SafeRelease(mD3DTexture);
88*8975f5c5SAndroid Build Coastguard Worker }
89*8975f5c5SAndroid Build Coastguard Worker
releaseSwapChain()90*8975f5c5SAndroid Build Coastguard Worker void SurfaceD3D::releaseSwapChain()
91*8975f5c5SAndroid Build Coastguard Worker {
92*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mSwapChain);
93*8975f5c5SAndroid Build Coastguard Worker }
94*8975f5c5SAndroid Build Coastguard Worker
initialize(const egl::Display * display)95*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::initialize(const egl::Display *display)
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker if (mNativeWindow->getNativeWindow())
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker if (!mNativeWindow->initialize())
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker return egl::EglBadSurface();
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker }
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
106*8975f5c5SAndroid Build Coastguard Worker {
107*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->getD3DTextureInfo(mState.config, mD3DTexture, mState.attributes,
108*8975f5c5SAndroid Build Coastguard Worker &mFixedWidth, &mFixedHeight, nullptr, nullptr,
109*8975f5c5SAndroid Build Coastguard Worker &mColorFormat, nullptr));
110*8975f5c5SAndroid Build Coastguard Worker if (mState.attributes.contains(EGL_GL_COLORSPACE))
111*8975f5c5SAndroid Build Coastguard Worker {
112*8975f5c5SAndroid Build Coastguard Worker if (mColorFormat->id != angle::FormatID::R8G8B8A8_TYPELESS &&
113*8975f5c5SAndroid Build Coastguard Worker mColorFormat->id != angle::FormatID::B8G8R8A8_TYPELESS)
114*8975f5c5SAndroid Build Coastguard Worker {
115*8975f5c5SAndroid Build Coastguard Worker return egl::EglBadMatch()
116*8975f5c5SAndroid Build Coastguard Worker << "EGL_GL_COLORSPACE may only be specified for TYPELESS textures";
117*8975f5c5SAndroid Build Coastguard Worker }
118*8975f5c5SAndroid Build Coastguard Worker }
119*8975f5c5SAndroid Build Coastguard Worker if (mColorFormat->id == angle::FormatID::R8G8B8A8_TYPELESS)
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker EGLAttrib colorspace =
122*8975f5c5SAndroid Build Coastguard Worker mState.attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR);
123*8975f5c5SAndroid Build Coastguard Worker if (colorspace == EGL_GL_COLORSPACE_SRGB)
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker mColorFormat = &angle::Format::Get(angle::FormatID::R8G8B8A8_TYPELESS_SRGB);
126*8975f5c5SAndroid Build Coastguard Worker }
127*8975f5c5SAndroid Build Coastguard Worker }
128*8975f5c5SAndroid Build Coastguard Worker if (mColorFormat->id == angle::FormatID::B8G8R8A8_TYPELESS)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker EGLAttrib colorspace =
131*8975f5c5SAndroid Build Coastguard Worker mState.attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR);
132*8975f5c5SAndroid Build Coastguard Worker if (colorspace == EGL_GL_COLORSPACE_SRGB)
133*8975f5c5SAndroid Build Coastguard Worker {
134*8975f5c5SAndroid Build Coastguard Worker mColorFormat = &angle::Format::Get(angle::FormatID::B8G8R8A8_TYPELESS_SRGB);
135*8975f5c5SAndroid Build Coastguard Worker }
136*8975f5c5SAndroid Build Coastguard Worker }
137*8975f5c5SAndroid Build Coastguard Worker mRenderTargetFormat = mColorFormat->fboImplementationInternalFormat;
138*8975f5c5SAndroid Build Coastguard Worker }
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(resetSwapChain(display));
141*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
142*8975f5c5SAndroid Build Coastguard Worker }
143*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context *,gl::Texture *,EGLint)144*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::bindTexImage(const gl::Context *, gl::Texture *, EGLint)
145*8975f5c5SAndroid Build Coastguard Worker {
146*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
147*8975f5c5SAndroid Build Coastguard Worker }
148*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context *,EGLint)149*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::releaseTexImage(const gl::Context *, EGLint)
150*8975f5c5SAndroid Build Coastguard Worker {
151*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
152*8975f5c5SAndroid Build Coastguard Worker }
153*8975f5c5SAndroid Build Coastguard Worker
getSyncValues(EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)154*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
155*8975f5c5SAndroid Build Coastguard Worker {
156*8975f5c5SAndroid Build Coastguard Worker if (!mState.directComposition)
157*8975f5c5SAndroid Build Coastguard Worker {
158*8975f5c5SAndroid Build Coastguard Worker return egl::EglBadSurface()
159*8975f5c5SAndroid Build Coastguard Worker << "getSyncValues: surface requires Direct Composition to be enabled";
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker return mSwapChain->getSyncValues(ust, msc, sbc);
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker
getMscRate(EGLint * numerator,EGLint * denominator)165*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::getMscRate(EGLint *numerator, EGLint *denominator)
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
168*8975f5c5SAndroid Build Coastguard Worker return egl::EglBadAccess();
169*8975f5c5SAndroid Build Coastguard Worker }
170*8975f5c5SAndroid Build Coastguard Worker
resetSwapChain(const egl::Display * display)171*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::resetSwapChain(const egl::Display *display)
172*8975f5c5SAndroid Build Coastguard Worker {
173*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mSwapChain);
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker int width;
176*8975f5c5SAndroid Build Coastguard Worker int height;
177*8975f5c5SAndroid Build Coastguard Worker
178*8975f5c5SAndroid Build Coastguard Worker if (!mFixedSize)
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker RECT windowRect;
181*8975f5c5SAndroid Build Coastguard Worker if (!mNativeWindow->getClientRect(&windowRect))
182*8975f5c5SAndroid Build Coastguard Worker {
183*8975f5c5SAndroid Build Coastguard Worker ASSERT(false);
184*8975f5c5SAndroid Build Coastguard Worker
185*8975f5c5SAndroid Build Coastguard Worker return egl::EglBadSurface() << "Could not retrieve the window dimensions";
186*8975f5c5SAndroid Build Coastguard Worker }
187*8975f5c5SAndroid Build Coastguard Worker
188*8975f5c5SAndroid Build Coastguard Worker width = windowRect.right - windowRect.left;
189*8975f5c5SAndroid Build Coastguard Worker height = windowRect.bottom - windowRect.top;
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker else
192*8975f5c5SAndroid Build Coastguard Worker {
193*8975f5c5SAndroid Build Coastguard Worker // non-window surface - size is determined at creation
194*8975f5c5SAndroid Build Coastguard Worker width = mFixedWidth;
195*8975f5c5SAndroid Build Coastguard Worker height = mFixedHeight;
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker mSwapChain =
199*8975f5c5SAndroid Build Coastguard Worker mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat,
200*8975f5c5SAndroid Build Coastguard Worker mDepthStencilFormat, mOrientation, mState.config->samples);
201*8975f5c5SAndroid Build Coastguard Worker if (!mSwapChain)
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker return egl::EglBadAlloc();
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Worker // This is a bit risky to pass the proxy context here, but it can happen at almost any time.
207*8975f5c5SAndroid Build Coastguard Worker DisplayD3D *displayD3D = GetImplAs<DisplayD3D>(display);
208*8975f5c5SAndroid Build Coastguard Worker egl::Error error = resetSwapChain(displayD3D, width, height);
209*8975f5c5SAndroid Build Coastguard Worker if (error.isError())
210*8975f5c5SAndroid Build Coastguard Worker {
211*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mSwapChain);
212*8975f5c5SAndroid Build Coastguard Worker return error;
213*8975f5c5SAndroid Build Coastguard Worker }
214*8975f5c5SAndroid Build Coastguard Worker
215*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker
resizeSwapChain(DisplayD3D * displayD3D,int backbufferWidth,int backbufferHeight)218*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::resizeSwapChain(DisplayD3D *displayD3D,
219*8975f5c5SAndroid Build Coastguard Worker int backbufferWidth,
220*8975f5c5SAndroid Build Coastguard Worker int backbufferHeight)
221*8975f5c5SAndroid Build Coastguard Worker {
222*8975f5c5SAndroid Build Coastguard Worker ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
223*8975f5c5SAndroid Build Coastguard Worker ASSERT(mSwapChain);
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker EGLint status =
226*8975f5c5SAndroid Build Coastguard Worker mSwapChain->resize(displayD3D, std::max(1, backbufferWidth), std::max(1, backbufferHeight));
227*8975f5c5SAndroid Build Coastguard Worker
228*8975f5c5SAndroid Build Coastguard Worker if (status == EGL_CONTEXT_LOST)
229*8975f5c5SAndroid Build Coastguard Worker {
230*8975f5c5SAndroid Build Coastguard Worker mDisplay->notifyDeviceLost();
231*8975f5c5SAndroid Build Coastguard Worker return egl::Error(status);
232*8975f5c5SAndroid Build Coastguard Worker }
233*8975f5c5SAndroid Build Coastguard Worker else if (status != EGL_SUCCESS)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker return egl::Error(status);
236*8975f5c5SAndroid Build Coastguard Worker }
237*8975f5c5SAndroid Build Coastguard Worker
238*8975f5c5SAndroid Build Coastguard Worker mWidth = backbufferWidth;
239*8975f5c5SAndroid Build Coastguard Worker mHeight = backbufferHeight;
240*8975f5c5SAndroid Build Coastguard Worker
241*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
242*8975f5c5SAndroid Build Coastguard Worker }
243*8975f5c5SAndroid Build Coastguard Worker
resetSwapChain(DisplayD3D * displayD3D,int backbufferWidth,int backbufferHeight)244*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::resetSwapChain(DisplayD3D *displayD3D,
245*8975f5c5SAndroid Build Coastguard Worker int backbufferWidth,
246*8975f5c5SAndroid Build Coastguard Worker int backbufferHeight)
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
249*8975f5c5SAndroid Build Coastguard Worker ASSERT(mSwapChain);
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Worker EGLint status = mSwapChain->reset(displayD3D, std::max(1, backbufferWidth),
252*8975f5c5SAndroid Build Coastguard Worker std::max(1, backbufferHeight), mSwapInterval);
253*8975f5c5SAndroid Build Coastguard Worker
254*8975f5c5SAndroid Build Coastguard Worker if (status == EGL_CONTEXT_LOST)
255*8975f5c5SAndroid Build Coastguard Worker {
256*8975f5c5SAndroid Build Coastguard Worker mRenderer->notifyDeviceLost();
257*8975f5c5SAndroid Build Coastguard Worker return egl::Error(status);
258*8975f5c5SAndroid Build Coastguard Worker }
259*8975f5c5SAndroid Build Coastguard Worker else if (status != EGL_SUCCESS)
260*8975f5c5SAndroid Build Coastguard Worker {
261*8975f5c5SAndroid Build Coastguard Worker return egl::Error(status);
262*8975f5c5SAndroid Build Coastguard Worker }
263*8975f5c5SAndroid Build Coastguard Worker
264*8975f5c5SAndroid Build Coastguard Worker mWidth = backbufferWidth;
265*8975f5c5SAndroid Build Coastguard Worker mHeight = backbufferHeight;
266*8975f5c5SAndroid Build Coastguard Worker mSwapIntervalDirty = false;
267*8975f5c5SAndroid Build Coastguard Worker
268*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
269*8975f5c5SAndroid Build Coastguard Worker }
270*8975f5c5SAndroid Build Coastguard Worker
swapRect(DisplayD3D * displayD3D,EGLint x,EGLint y,EGLint width,EGLint height)271*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::swapRect(DisplayD3D *displayD3D,
272*8975f5c5SAndroid Build Coastguard Worker EGLint x,
273*8975f5c5SAndroid Build Coastguard Worker EGLint y,
274*8975f5c5SAndroid Build Coastguard Worker EGLint width,
275*8975f5c5SAndroid Build Coastguard Worker EGLint height)
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker if (!mSwapChain)
278*8975f5c5SAndroid Build Coastguard Worker {
279*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker if (x + width > mWidth)
283*8975f5c5SAndroid Build Coastguard Worker {
284*8975f5c5SAndroid Build Coastguard Worker width = mWidth - x;
285*8975f5c5SAndroid Build Coastguard Worker }
286*8975f5c5SAndroid Build Coastguard Worker
287*8975f5c5SAndroid Build Coastguard Worker if (y + height > mHeight)
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker height = mHeight - y;
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Worker if (width != 0 && height != 0)
293*8975f5c5SAndroid Build Coastguard Worker {
294*8975f5c5SAndroid Build Coastguard Worker EGLint status = mSwapChain->swapRect(displayD3D, x, y, width, height);
295*8975f5c5SAndroid Build Coastguard Worker
296*8975f5c5SAndroid Build Coastguard Worker if (status == EGL_CONTEXT_LOST)
297*8975f5c5SAndroid Build Coastguard Worker {
298*8975f5c5SAndroid Build Coastguard Worker mRenderer->notifyDeviceLost();
299*8975f5c5SAndroid Build Coastguard Worker return egl::Error(status);
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker else if (status != EGL_SUCCESS)
302*8975f5c5SAndroid Build Coastguard Worker {
303*8975f5c5SAndroid Build Coastguard Worker return egl::Error(status);
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker }
306*8975f5c5SAndroid Build Coastguard Worker
307*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(checkForOutOfDateSwapChain(displayD3D));
308*8975f5c5SAndroid Build Coastguard Worker
309*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
310*8975f5c5SAndroid Build Coastguard Worker }
311*8975f5c5SAndroid Build Coastguard Worker
checkForOutOfDateSwapChain(DisplayD3D * displayD3D)312*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::checkForOutOfDateSwapChain(DisplayD3D *displayD3D)
313*8975f5c5SAndroid Build Coastguard Worker {
314*8975f5c5SAndroid Build Coastguard Worker RECT client;
315*8975f5c5SAndroid Build Coastguard Worker int clientWidth = getWidth();
316*8975f5c5SAndroid Build Coastguard Worker int clientHeight = getHeight();
317*8975f5c5SAndroid Build Coastguard Worker bool sizeDirty = false;
318*8975f5c5SAndroid Build Coastguard Worker if (!mFixedSize && !mNativeWindow->isIconic())
319*8975f5c5SAndroid Build Coastguard Worker {
320*8975f5c5SAndroid Build Coastguard Worker // The window is automatically resized to 150x22 when it's minimized, but the swapchain
321*8975f5c5SAndroid Build Coastguard Worker // shouldn't be resized because that's not a useful size to render to.
322*8975f5c5SAndroid Build Coastguard Worker if (!mNativeWindow->getClientRect(&client))
323*8975f5c5SAndroid Build Coastguard Worker {
324*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
325*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker
328*8975f5c5SAndroid Build Coastguard Worker // Grow the buffer now, if the window has grown. We need to grow now to avoid losing
329*8975f5c5SAndroid Build Coastguard Worker // information.
330*8975f5c5SAndroid Build Coastguard Worker clientWidth = client.right - client.left;
331*8975f5c5SAndroid Build Coastguard Worker clientHeight = client.bottom - client.top;
332*8975f5c5SAndroid Build Coastguard Worker sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
333*8975f5c5SAndroid Build Coastguard Worker }
334*8975f5c5SAndroid Build Coastguard Worker else if (mFixedSize)
335*8975f5c5SAndroid Build Coastguard Worker {
336*8975f5c5SAndroid Build Coastguard Worker clientWidth = mFixedWidth;
337*8975f5c5SAndroid Build Coastguard Worker clientHeight = mFixedHeight;
338*8975f5c5SAndroid Build Coastguard Worker sizeDirty = mFixedWidth != getWidth() || mFixedHeight != getHeight();
339*8975f5c5SAndroid Build Coastguard Worker }
340*8975f5c5SAndroid Build Coastguard Worker
341*8975f5c5SAndroid Build Coastguard Worker if (mSwapIntervalDirty)
342*8975f5c5SAndroid Build Coastguard Worker {
343*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(resetSwapChain(displayD3D, clientWidth, clientHeight));
344*8975f5c5SAndroid Build Coastguard Worker }
345*8975f5c5SAndroid Build Coastguard Worker else if (sizeDirty)
346*8975f5c5SAndroid Build Coastguard Worker {
347*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(resizeSwapChain(displayD3D, clientWidth, clientHeight));
348*8975f5c5SAndroid Build Coastguard Worker }
349*8975f5c5SAndroid Build Coastguard Worker
350*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
351*8975f5c5SAndroid Build Coastguard Worker }
352*8975f5c5SAndroid Build Coastguard Worker
swap(const gl::Context * context)353*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::swap(const gl::Context *context)
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker DisplayD3D *displayD3D = GetImplAs<DisplayD3D>(context->getDisplay());
356*8975f5c5SAndroid Build Coastguard Worker return swapRect(displayD3D, 0, 0, mWidth, mHeight);
357*8975f5c5SAndroid Build Coastguard Worker }
358*8975f5c5SAndroid Build Coastguard Worker
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)359*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::postSubBuffer(const gl::Context *context,
360*8975f5c5SAndroid Build Coastguard Worker EGLint x,
361*8975f5c5SAndroid Build Coastguard Worker EGLint y,
362*8975f5c5SAndroid Build Coastguard Worker EGLint width,
363*8975f5c5SAndroid Build Coastguard Worker EGLint height)
364*8975f5c5SAndroid Build Coastguard Worker {
365*8975f5c5SAndroid Build Coastguard Worker DisplayD3D *displayD3D = GetImplAs<DisplayD3D>(context->getDisplay());
366*8975f5c5SAndroid Build Coastguard Worker return swapRect(displayD3D, x, y, width, height);
367*8975f5c5SAndroid Build Coastguard Worker }
368*8975f5c5SAndroid Build Coastguard Worker
getSwapChain() const369*8975f5c5SAndroid Build Coastguard Worker rx::SwapChainD3D *SurfaceD3D::getSwapChain() const
370*8975f5c5SAndroid Build Coastguard Worker {
371*8975f5c5SAndroid Build Coastguard Worker return mSwapChain;
372*8975f5c5SAndroid Build Coastguard Worker }
373*8975f5c5SAndroid Build Coastguard Worker
setSwapInterval(const egl::Display * display,EGLint interval)374*8975f5c5SAndroid Build Coastguard Worker void SurfaceD3D::setSwapInterval(const egl::Display *display, EGLint interval)
375*8975f5c5SAndroid Build Coastguard Worker {
376*8975f5c5SAndroid Build Coastguard Worker if (mSwapInterval == interval)
377*8975f5c5SAndroid Build Coastguard Worker {
378*8975f5c5SAndroid Build Coastguard Worker return;
379*8975f5c5SAndroid Build Coastguard Worker }
380*8975f5c5SAndroid Build Coastguard Worker
381*8975f5c5SAndroid Build Coastguard Worker mSwapInterval = interval;
382*8975f5c5SAndroid Build Coastguard Worker mSwapIntervalDirty = true;
383*8975f5c5SAndroid Build Coastguard Worker }
384*8975f5c5SAndroid Build Coastguard Worker
setFixedWidth(EGLint width)385*8975f5c5SAndroid Build Coastguard Worker void SurfaceD3D::setFixedWidth(EGLint width)
386*8975f5c5SAndroid Build Coastguard Worker {
387*8975f5c5SAndroid Build Coastguard Worker mFixedWidth = width;
388*8975f5c5SAndroid Build Coastguard Worker }
389*8975f5c5SAndroid Build Coastguard Worker
setFixedHeight(EGLint height)390*8975f5c5SAndroid Build Coastguard Worker void SurfaceD3D::setFixedHeight(EGLint height)
391*8975f5c5SAndroid Build Coastguard Worker {
392*8975f5c5SAndroid Build Coastguard Worker mFixedHeight = height;
393*8975f5c5SAndroid Build Coastguard Worker }
394*8975f5c5SAndroid Build Coastguard Worker
getWidth() const395*8975f5c5SAndroid Build Coastguard Worker EGLint SurfaceD3D::getWidth() const
396*8975f5c5SAndroid Build Coastguard Worker {
397*8975f5c5SAndroid Build Coastguard Worker return mWidth;
398*8975f5c5SAndroid Build Coastguard Worker }
399*8975f5c5SAndroid Build Coastguard Worker
getHeight() const400*8975f5c5SAndroid Build Coastguard Worker EGLint SurfaceD3D::getHeight() const
401*8975f5c5SAndroid Build Coastguard Worker {
402*8975f5c5SAndroid Build Coastguard Worker return mHeight;
403*8975f5c5SAndroid Build Coastguard Worker }
404*8975f5c5SAndroid Build Coastguard Worker
isPostSubBufferSupported() const405*8975f5c5SAndroid Build Coastguard Worker EGLint SurfaceD3D::isPostSubBufferSupported() const
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker // post sub buffer is always possible on D3D surfaces
408*8975f5c5SAndroid Build Coastguard Worker return EGL_TRUE;
409*8975f5c5SAndroid Build Coastguard Worker }
410*8975f5c5SAndroid Build Coastguard Worker
getSwapBehavior() const411*8975f5c5SAndroid Build Coastguard Worker EGLint SurfaceD3D::getSwapBehavior() const
412*8975f5c5SAndroid Build Coastguard Worker {
413*8975f5c5SAndroid Build Coastguard Worker return EGL_BUFFER_PRESERVED;
414*8975f5c5SAndroid Build Coastguard Worker }
415*8975f5c5SAndroid Build Coastguard Worker
querySurfacePointerANGLE(EGLint attribute,void ** value)416*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value)
417*8975f5c5SAndroid Build Coastguard Worker {
418*8975f5c5SAndroid Build Coastguard Worker if (attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker *value = mSwapChain->getShareHandle();
421*8975f5c5SAndroid Build Coastguard Worker }
422*8975f5c5SAndroid Build Coastguard Worker else if (attribute == EGL_DXGI_KEYED_MUTEX_ANGLE)
423*8975f5c5SAndroid Build Coastguard Worker {
424*8975f5c5SAndroid Build Coastguard Worker *value = mSwapChain->getKeyedMutex();
425*8975f5c5SAndroid Build Coastguard Worker }
426*8975f5c5SAndroid Build Coastguard Worker else
427*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
428*8975f5c5SAndroid Build Coastguard Worker
429*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
430*8975f5c5SAndroid Build Coastguard Worker }
431*8975f5c5SAndroid Build Coastguard Worker
getD3DTextureColorFormat() const432*8975f5c5SAndroid Build Coastguard Worker const angle::Format *SurfaceD3D::getD3DTextureColorFormat() const
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker return mColorFormat;
435*8975f5c5SAndroid Build Coastguard Worker }
436*8975f5c5SAndroid Build Coastguard Worker
attachToFramebuffer(const gl::Context * context,gl::Framebuffer * framebuffer)437*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::attachToFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
438*8975f5c5SAndroid Build Coastguard Worker {
439*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
440*8975f5c5SAndroid Build Coastguard Worker }
441*8975f5c5SAndroid Build Coastguard Worker
detachFromFramebuffer(const gl::Context * context,gl::Framebuffer * framebuffer)442*8975f5c5SAndroid Build Coastguard Worker egl::Error SurfaceD3D::detachFromFramebuffer(const gl::Context *context,
443*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *framebuffer)
444*8975f5c5SAndroid Build Coastguard Worker {
445*8975f5c5SAndroid Build Coastguard Worker return egl::NoError();
446*8975f5c5SAndroid Build Coastguard Worker }
447*8975f5c5SAndroid Build Coastguard Worker
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)448*8975f5c5SAndroid Build Coastguard Worker angle::Result SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context,
449*8975f5c5SAndroid Build Coastguard Worker GLenum binding,
450*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &imageIndex,
451*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
452*8975f5c5SAndroid Build Coastguard Worker FramebufferAttachmentRenderTarget **rtOut)
453*8975f5c5SAndroid Build Coastguard Worker {
454*8975f5c5SAndroid Build Coastguard Worker if (binding == GL_BACK)
455*8975f5c5SAndroid Build Coastguard Worker {
456*8975f5c5SAndroid Build Coastguard Worker *rtOut = mSwapChain->getColorRenderTarget();
457*8975f5c5SAndroid Build Coastguard Worker }
458*8975f5c5SAndroid Build Coastguard Worker else
459*8975f5c5SAndroid Build Coastguard Worker {
460*8975f5c5SAndroid Build Coastguard Worker *rtOut = mSwapChain->getDepthStencilRenderTarget();
461*8975f5c5SAndroid Build Coastguard Worker }
462*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
463*8975f5c5SAndroid Build Coastguard Worker }
464*8975f5c5SAndroid Build Coastguard Worker
initializeContents(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex)465*8975f5c5SAndroid Build Coastguard Worker angle::Result SurfaceD3D::initializeContents(const gl::Context *context,
466*8975f5c5SAndroid Build Coastguard Worker GLenum binding,
467*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &imageIndex)
468*8975f5c5SAndroid Build Coastguard Worker {
469*8975f5c5SAndroid Build Coastguard Worker switch (binding)
470*8975f5c5SAndroid Build Coastguard Worker {
471*8975f5c5SAndroid Build Coastguard Worker case GL_BACK:
472*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.config->renderTargetFormat != GL_NONE);
473*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->initRenderTarget(context, mSwapChain->getColorRenderTarget()));
474*8975f5c5SAndroid Build Coastguard Worker break;
475*8975f5c5SAndroid Build Coastguard Worker
476*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH:
477*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL:
478*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.config->depthStencilFormat != GL_NONE);
479*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
480*8975f5c5SAndroid Build Coastguard Worker mRenderer->initRenderTarget(context, mSwapChain->getDepthStencilRenderTarget()));
481*8975f5c5SAndroid Build Coastguard Worker break;
482*8975f5c5SAndroid Build Coastguard Worker
483*8975f5c5SAndroid Build Coastguard Worker default:
484*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
485*8975f5c5SAndroid Build Coastguard Worker break;
486*8975f5c5SAndroid Build Coastguard Worker }
487*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
488*8975f5c5SAndroid Build Coastguard Worker }
489*8975f5c5SAndroid Build Coastguard Worker
WindowSurfaceD3D(const egl::SurfaceState & state,RendererD3D * renderer,egl::Display * display,EGLNativeWindowType window,const egl::AttributeMap & attribs)490*8975f5c5SAndroid Build Coastguard Worker WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
491*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
492*8975f5c5SAndroid Build Coastguard Worker egl::Display *display,
493*8975f5c5SAndroid Build Coastguard Worker EGLNativeWindowType window,
494*8975f5c5SAndroid Build Coastguard Worker const egl::AttributeMap &attribs)
495*8975f5c5SAndroid Build Coastguard Worker : SurfaceD3D(state, renderer, display, window, 0, static_cast<EGLClientBuffer>(0), attribs)
496*8975f5c5SAndroid Build Coastguard Worker {}
497*8975f5c5SAndroid Build Coastguard Worker
~WindowSurfaceD3D()498*8975f5c5SAndroid Build Coastguard Worker WindowSurfaceD3D::~WindowSurfaceD3D() {}
499*8975f5c5SAndroid Build Coastguard Worker
PbufferSurfaceD3D(const egl::SurfaceState & state,RendererD3D * renderer,egl::Display * display,EGLenum buftype,EGLClientBuffer clientBuffer,const egl::AttributeMap & attribs)500*8975f5c5SAndroid Build Coastguard Worker PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state,
501*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
502*8975f5c5SAndroid Build Coastguard Worker egl::Display *display,
503*8975f5c5SAndroid Build Coastguard Worker EGLenum buftype,
504*8975f5c5SAndroid Build Coastguard Worker EGLClientBuffer clientBuffer,
505*8975f5c5SAndroid Build Coastguard Worker const egl::AttributeMap &attribs)
506*8975f5c5SAndroid Build Coastguard Worker : SurfaceD3D(state,
507*8975f5c5SAndroid Build Coastguard Worker renderer,
508*8975f5c5SAndroid Build Coastguard Worker display,
509*8975f5c5SAndroid Build Coastguard Worker static_cast<EGLNativeWindowType>(0),
510*8975f5c5SAndroid Build Coastguard Worker buftype,
511*8975f5c5SAndroid Build Coastguard Worker clientBuffer,
512*8975f5c5SAndroid Build Coastguard Worker attribs)
513*8975f5c5SAndroid Build Coastguard Worker {}
514*8975f5c5SAndroid Build Coastguard Worker
~PbufferSurfaceD3D()515*8975f5c5SAndroid Build Coastguard Worker PbufferSurfaceD3D::~PbufferSurfaceD3D() {}
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
518