Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
8 // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
10 #include "libGLESv2/renderer/SwapChain11.h"
12 #include "libGLESv2/renderer/renderer11_utils.h"
13 #include "libGLESv2/renderer/Renderer11.h"
14 #include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h"
15 #include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h"
17 namespace rx
18 {
20 SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
21 GLenum backBufferFormat, GLenum depthBufferFormat)
22 : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
23 {
24 mSwapChain = NULL;
25 mBackBufferTexture = NULL;
26 mBackBufferRTView = NULL;
27 mOffscreenTexture = NULL;
28 mOffscreenRTView = NULL;
29 mOffscreenSRView = NULL;
30 mDepthStencilTexture = NULL;
31 mDepthStencilDSView = NULL;
32 mQuadVB = NULL;
33 mPassThroughSampler = NULL;
34 mPassThroughIL = NULL;
35 mPassThroughVS = NULL;
36 mPassThroughPS = NULL;
37 mWidth = -1;
38 mHeight = -1;
39 mSwapInterval = 0;
40 mAppCreatedShareHandle = mShareHandle != NULL;
41 mPassThroughResourcesInit = false;
42 }
44 SwapChain11::~SwapChain11()
45 {
46 release();
47 }
49 void SwapChain11::release()
50 {
51 if (mSwapChain)
52 {
53 mSwapChain->Release();
54 mSwapChain = NULL;
55 }
57 if (mBackBufferTexture)
58 {
59 mBackBufferTexture->Release();
60 mBackBufferTexture = NULL;
61 }
63 if (mBackBufferRTView)
64 {
65 mBackBufferRTView->Release();
66 mBackBufferRTView = NULL;
67 }
69 if (mOffscreenTexture)
70 {
71 mOffscreenTexture->Release();
72 mOffscreenTexture = NULL;
73 }
75 if (mOffscreenRTView)
76 {
77 mOffscreenRTView->Release();
78 mOffscreenRTView = NULL;
79 }
81 if (mOffscreenSRView)
82 {
83 mOffscreenSRView->Release();
84 mOffscreenSRView = NULL;
85 }
87 if (mDepthStencilTexture)
88 {
89 mDepthStencilTexture->Release();
90 mDepthStencilTexture = NULL;
91 }
93 if (mDepthStencilDSView)
94 {
95 mDepthStencilDSView->Release();
96 mDepthStencilDSView = NULL;
97 }
99 if (mQuadVB)
100 {
101 mQuadVB->Release();
102 mQuadVB = NULL;
103 }
105 if (mPassThroughSampler)
106 {
107 mPassThroughSampler->Release();
108 mPassThroughSampler = NULL;
109 }
111 if (mPassThroughIL)
112 {
113 mPassThroughIL->Release();
114 mPassThroughIL = NULL;
115 }
117 if (mPassThroughVS)
118 {
119 mPassThroughVS->Release();
120 mPassThroughVS = NULL;
121 }
123 if (mPassThroughPS)
124 {
125 mPassThroughPS->Release();
126 mPassThroughPS = NULL;
127 }
129 if (!mAppCreatedShareHandle)
130 {
131 mShareHandle = NULL;
132 }
133 }
135 void SwapChain11::releaseOffscreenTexture()
136 {
137 if (mOffscreenTexture)
138 {
139 mOffscreenTexture->Release();
140 mOffscreenTexture = NULL;
141 }
143 if (mOffscreenRTView)
144 {
145 mOffscreenRTView->Release();
146 mOffscreenRTView = NULL;
147 }
149 if (mOffscreenSRView)
150 {
151 mOffscreenSRView->Release();
152 mOffscreenSRView = NULL;
153 }
155 if (mDepthStencilTexture)
156 {
157 mDepthStencilTexture->Release();
158 mDepthStencilTexture = NULL;
159 }
161 if (mDepthStencilDSView)
162 {
163 mDepthStencilDSView->Release();
164 mDepthStencilDSView = NULL;
165 }
166 }
168 EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
169 {
170 ID3D11Device *device = mRenderer->getDevice();
172 ASSERT(device != NULL);
174 // D3D11 does not allow zero size textures
175 ASSERT(backbufferWidth >= 1);
176 ASSERT(backbufferHeight >= 1);
178 // Preserve the render target content
179 ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
180 if (previousOffscreenTexture)
181 {
182 previousOffscreenTexture->AddRef();
183 }
184 const int previousWidth = mWidth;
185 const int previousHeight = mHeight;
187 releaseOffscreenTexture();
189 // If the app passed in a share handle, open the resource
190 // See EGL_ANGLE_d3d_share_handle_client_buffer
191 if (mAppCreatedShareHandle)
192 {
193 ID3D11Resource *tempResource11;
194 HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
196 if (FAILED(result))
197 {
198 ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
199 release();
200 return EGL_BAD_PARAMETER;
201 }
203 result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
204 tempResource11->Release();
206 if (FAILED(result))
207 {
208 ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
209 release();
210 return EGL_BAD_PARAMETER;
211 }
213 // Validate offscreen texture parameters
214 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
215 mOffscreenTexture->GetDesc(&offscreenTextureDesc);
217 if (offscreenTextureDesc.Width != (UINT)backbufferWidth
218 || offscreenTextureDesc.Height != (UINT)backbufferHeight
219 || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
220 || offscreenTextureDesc.MipLevels != 1
221 || offscreenTextureDesc.ArraySize != 1)
222 {
223 ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
224 release();
225 return EGL_BAD_PARAMETER;
226 }
227 }
228 else
229 {
230 const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
232 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
233 offscreenTextureDesc.Width = backbufferWidth;
234 offscreenTextureDesc.Height = backbufferHeight;
235 offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
236 offscreenTextureDesc.MipLevels = 1;
237 offscreenTextureDesc.ArraySize = 1;
238 offscreenTextureDesc.SampleDesc.Count = 1;
239 offscreenTextureDesc.SampleDesc.Quality = 0;
240 offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
241 offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
242 offscreenTextureDesc.CPUAccessFlags = 0;
243 offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
245 HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
247 if (FAILED(result))
248 {
249 ERR("Could not create offscreen texture: %08lX", result);
250 release();
252 if (d3d11::isDeviceLostError(result))
253 {
254 return EGL_CONTEXT_LOST;
255 }
256 else
257 {
258 return EGL_BAD_ALLOC;
259 }
260 }
262 d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture");
264 // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
265 if (useSharedResource)
266 {
267 IDXGIResource *offscreenTextureResource = NULL;
268 result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource);
270 // Fall back to no share handle on failure
271 if (FAILED(result))
272 {
273 ERR("Could not query offscreen texture resource: %08lX", result);
274 }
275 else
276 {
277 result = offscreenTextureResource->GetSharedHandle(&mShareHandle);
279 if (FAILED(result))
280 {
281 mShareHandle = NULL;
282 ERR("Could not get offscreen texture shared handle: %08lX", result);
283 }
284 }
285 }
286 }
288 HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView);
290 ASSERT(SUCCEEDED(result));
291 d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target");
293 result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView);
294 ASSERT(SUCCEEDED(result));
295 d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource");
297 if (mDepthBufferFormat != GL_NONE)
298 {
299 D3D11_TEXTURE2D_DESC depthStencilDesc = {0};
300 depthStencilDesc.Width = backbufferWidth;
301 depthStencilDesc.Height = backbufferHeight;
302 depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);
303 depthStencilDesc.MipLevels = 1;
304 depthStencilDesc.ArraySize = 1;
305 depthStencilDesc.SampleDesc.Count = 1;
306 depthStencilDesc.SampleDesc.Quality = 0;
307 depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
308 depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
309 depthStencilDesc.CPUAccessFlags = 0;
310 depthStencilDesc.MiscFlags = 0;
312 result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture);
313 if (FAILED(result))
314 {
315 ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
316 release();
318 if (d3d11::isDeviceLostError(result))
319 {
320 return EGL_CONTEXT_LOST;
321 }
322 else
323 {
324 return EGL_BAD_ALLOC;
325 }
326 }
327 d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture");
329 result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView);
330 ASSERT(SUCCEEDED(result));
331 d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view");
332 }
334 mWidth = backbufferWidth;
335 mHeight = backbufferHeight;
337 if (previousOffscreenTexture != NULL)
338 {
339 D3D11_BOX sourceBox = {0};
340 sourceBox.left = 0;
341 sourceBox.right = std::min(previousWidth, mWidth);
342 sourceBox.top = std::max(previousHeight - mHeight, 0);
343 sourceBox.bottom = previousHeight;
344 sourceBox.front = 0;
345 sourceBox.back = 1;
347 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
348 const int yoffset = std::max(mHeight - previousHeight, 0);
349 deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox);
351 previousOffscreenTexture->Release();
353 if (mSwapChain)
354 {
355 swapRect(0, 0, mWidth, mHeight);
356 }
357 }
359 return EGL_SUCCESS;
360 }
362 EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
363 {
364 ID3D11Device *device = mRenderer->getDevice();
366 if (device == NULL)
367 {
368 return EGL_BAD_ACCESS;
369 }
371 // Can only call resize if we have already created our swap buffer and resources
372 ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
374 if (mBackBufferTexture)
375 {
376 mBackBufferTexture->Release();
377 mBackBufferTexture = NULL;
378 }
380 if (mBackBufferRTView)
381 {
382 mBackBufferRTView->Release();
383 mBackBufferRTView = NULL;
384 }
386 // Resize swap chain
387 DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
388 HRESULT result = mSwapChain->ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0);
390 if (FAILED(result))
391 {
392 ERR("Error resizing swap chain buffers: 0x%08X", result);
393 release();
395 if (d3d11::isDeviceLostError(result))
396 {
397 return EGL_CONTEXT_LOST;
398 }
399 else
400 {
401 return EGL_BAD_ALLOC;
402 }
403 }
405 result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
406 ASSERT(SUCCEEDED(result));
407 if (SUCCEEDED(result))
408 {
409 d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
410 }
412 result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
413 ASSERT(SUCCEEDED(result));
414 if (SUCCEEDED(result))
415 {
416 d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
417 }
419 return resetOffscreenTexture(backbufferWidth, backbufferHeight);
420 }
422 EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
423 {
424 ID3D11Device *device = mRenderer->getDevice();
426 if (device == NULL)
427 {
428 return EGL_BAD_ACCESS;
429 }
431 // Release specific resources to free up memory for the new render target, while the
432 // old render target still exists for the purpose of preserving its contents.
433 if (mSwapChain)
434 {
435 mSwapChain->Release();
436 mSwapChain = NULL;
437 }
439 if (mBackBufferTexture)
440 {
441 mBackBufferTexture->Release();
442 mBackBufferTexture = NULL;
443 }
445 if (mBackBufferRTView)
446 {
447 mBackBufferRTView->Release();
448 mBackBufferRTView = NULL;
449 }
451 mSwapInterval = static_cast<unsigned int>(swapInterval);
452 if (mSwapInterval > 4)
453 {
454 // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range
455 return EGL_BAD_PARAMETER;
456 }
458 // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
459 if (backbufferWidth < 1 || backbufferHeight < 1)
460 {
461 releaseOffscreenTexture();
462 return EGL_SUCCESS;
463 }
465 if (mWindow)
466 {
467 // We cannot create a swap chain for an HWND that is owned by a different process
468 DWORD currentProcessId = GetCurrentProcessId();
469 DWORD wndProcessId;
470 GetWindowThreadProcessId(mWindow, &wndProcessId);
472 if (currentProcessId != wndProcessId)
473 {
474 ERR("Could not create swap chain, window owned by different process");
475 release();
476 return EGL_BAD_NATIVE_WINDOW;
477 }
479 IDXGIFactory *factory = mRenderer->getDxgiFactory();
481 DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
482 swapChainDesc.BufferCount = 2;
483 swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
484 swapChainDesc.BufferDesc.Width = backbufferWidth;
485 swapChainDesc.BufferDesc.Height = backbufferHeight;
486 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
487 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
488 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
489 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
490 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
491 swapChainDesc.Flags = 0;
492 swapChainDesc.OutputWindow = mWindow;
493 swapChainDesc.SampleDesc.Count = 1;
494 swapChainDesc.SampleDesc.Quality = 0;
495 swapChainDesc.Windowed = TRUE;
497 HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
499 if (FAILED(result))
500 {
501 ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
502 release();
504 if (d3d11::isDeviceLostError(result))
505 {
506 return EGL_CONTEXT_LOST;
507 }
508 else
509 {
510 return EGL_BAD_ALLOC;
511 }
512 }
514 result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
515 ASSERT(SUCCEEDED(result));
516 d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
518 result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
519 ASSERT(SUCCEEDED(result));
520 d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
521 }
523 // If we are resizing the swap chain, we don't wish to recreate all the static resources
524 if (!mPassThroughResourcesInit)
525 {
526 mPassThroughResourcesInit = true;
527 initPassThroughResources();
528 }
530 return resetOffscreenTexture(backbufferWidth, backbufferHeight);
531 }
533 void SwapChain11::initPassThroughResources()
534 {
535 ID3D11Device *device = mRenderer->getDevice();
537 ASSERT(device != NULL);
539 // Make sure our resources are all not allocated, when we create
540 ASSERT(mQuadVB == NULL && mPassThroughSampler == NULL);
541 ASSERT(mPassThroughIL == NULL && mPassThroughVS == NULL && mPassThroughPS == NULL);
543 D3D11_BUFFER_DESC vbDesc;
544 vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
545 vbDesc.Usage = D3D11_USAGE_DYNAMIC;
546 vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
547 vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
548 vbDesc.MiscFlags = 0;
549 vbDesc.StructureByteStride = 0;
551 HRESULT result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB);
552 ASSERT(SUCCEEDED(result));
553 d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer");
555 D3D11_SAMPLER_DESC samplerDesc;
556 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
557 samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
558 samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
559 samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
560 samplerDesc.MipLODBias = 0.0f;
561 samplerDesc.MaxAnisotropy = 0;
562 samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
563 samplerDesc.BorderColor[0] = 0.0f;
564 samplerDesc.BorderColor[1] = 0.0f;
565 samplerDesc.BorderColor[2] = 0.0f;
566 samplerDesc.BorderColor[3] = 0.0f;
567 samplerDesc.MinLOD = 0;
568 samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
570 result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
571 ASSERT(SUCCEEDED(result));
572 d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler");
574 D3D11_INPUT_ELEMENT_DESC quadLayout[] =
575 {
576 { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
577 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
578 };
580 result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL);
581 ASSERT(SUCCEEDED(result));
582 d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout");
584 result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS);
585 ASSERT(SUCCEEDED(result));
586 d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader");
588 result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS);
589 ASSERT(SUCCEEDED(result));
590 d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
591 }
593 // parameters should be validated/clamped by caller
594 EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
595 {
596 if (!mSwapChain)
597 {
598 return EGL_SUCCESS;
599 }
601 ID3D11Device *device = mRenderer->getDevice();
602 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
604 // Set vertices
605 D3D11_MAPPED_SUBRESOURCE mappedResource;
606 HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
607 if (FAILED(result))
608 {
609 return EGL_BAD_ACCESS;
610 }
612 d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
614 // Create a quad in homogeneous coordinates
615 float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
616 float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
617 float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
618 float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
620 float u1 = x / float(mWidth);
621 float v1 = y / float(mHeight);
622 float u2 = (x + width) / float(mWidth);
623 float v2 = (y + height) / float(mHeight);
625 d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
626 d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
627 d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
628 d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
630 deviceContext->Unmap(mQuadVB, 0);
632 static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
633 static UINT startIdx = 0;
634 deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx);
636 // Apply state
637 deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
639 static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
640 deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
642 deviceContext->RSSetState(NULL);
644 // Apply shaders
645 deviceContext->IASetInputLayout(mPassThroughIL);
646 deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
647 deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
648 deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
649 deviceContext->GSSetShader(NULL, NULL, 0);
651 // Apply render targets
652 mRenderer->setOneTimeRenderTarget(mBackBufferRTView);
654 // Set the viewport
655 D3D11_VIEWPORT viewport;
656 viewport.TopLeftX = 0;
657 viewport.TopLeftY = 0;
658 viewport.Width = mWidth;
659 viewport.Height = mHeight;
660 viewport.MinDepth = 0.0f;
661 viewport.MaxDepth = 1.0f;
662 deviceContext->RSSetViewports(1, &viewport);
664 // Apply textures
665 deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
666 deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
668 // Draw
669 deviceContext->Draw(4, 0);
670 result = mSwapChain->Present(mSwapInterval, 0);
672 if (result == DXGI_ERROR_DEVICE_REMOVED)
673 {
674 HRESULT removedReason = device->GetDeviceRemovedReason();
675 ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason);
676 return EGL_CONTEXT_LOST;
677 }
678 else if (result == DXGI_ERROR_DEVICE_RESET)
679 {
680 ERR("Present failed: the D3D11 device was reset from a bad command.");
681 return EGL_CONTEXT_LOST;
682 }
683 else if (FAILED(result))
684 {
685 ERR("Present failed with error code 0x%08X", result);
686 }
688 // Unbind
689 static ID3D11ShaderResourceView *const nullSRV = NULL;
690 deviceContext->PSSetShaderResources(0, 1, &nullSRV);
692 mRenderer->unapplyRenderTargets();
693 mRenderer->markAllStateDirty();
695 return EGL_SUCCESS;
696 }
698 // Increments refcount on texture.
699 // caller must Release() the returned texture
700 ID3D11Texture2D *SwapChain11::getOffscreenTexture()
701 {
702 if (mOffscreenTexture)
703 {
704 mOffscreenTexture->AddRef();
705 }
707 return mOffscreenTexture;
708 }
710 // Increments refcount on view.
711 // caller must Release() the returned view
712 ID3D11RenderTargetView *SwapChain11::getRenderTarget()
713 {
714 if (mOffscreenRTView)
715 {
716 mOffscreenRTView->AddRef();
717 }
719 return mOffscreenRTView;
720 }
722 // Increments refcount on view.
723 // caller must Release() the returned view
724 ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
725 {
726 if (mOffscreenSRView)
727 {
728 mOffscreenSRView->AddRef();
729 }
731 return mOffscreenSRView;
732 }
734 // Increments refcount on view.
735 // caller must Release() the returned view
736 ID3D11DepthStencilView *SwapChain11::getDepthStencil()
737 {
738 if (mDepthStencilDSView)
739 {
740 mDepthStencilDSView->AddRef();
741 }
743 return mDepthStencilDSView;
744 }
746 ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
747 {
748 if (mDepthStencilTexture)
749 {
750 mDepthStencilTexture->AddRef();
751 }
753 return mDepthStencilTexture;
754 }
756 SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
757 {
758 ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
759 return static_cast<rx::SwapChain11*>(swapChain);
760 }
762 void SwapChain11::recreate()
763 {
764 // possibly should use this method instead of reset
765 }
767 }