gfx/angle/src/libGLESv2/renderer/SwapChain9.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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 // SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
    10 #include "libGLESv2/renderer/SwapChain9.h"
    11 #include "libGLESv2/renderer/renderer9_utils.h"
    12 #include "libGLESv2/renderer/Renderer9.h"
    14 namespace rx
    15 {
    17 SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
    18                        GLenum backBufferFormat, GLenum depthBufferFormat)
    19     : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
    20 {
    21     mSwapChain = NULL;
    22     mBackBuffer = NULL;
    23     mDepthStencil = NULL;
    24     mRenderTarget = NULL;
    25     mOffscreenTexture = NULL;
    26     mWidth = -1;
    27     mHeight = -1;
    28     mSwapInterval = -1;
    29 }
    31 SwapChain9::~SwapChain9()
    32 {
    33     release();
    34 }
    36 void SwapChain9::release()
    37 {
    38     if (mSwapChain)
    39     {
    40         mSwapChain->Release();
    41         mSwapChain = NULL;
    42     }
    44     if (mBackBuffer)
    45     {
    46         mBackBuffer->Release();
    47         mBackBuffer = NULL;
    48     }
    50     if (mDepthStencil)
    51     {
    52         mDepthStencil->Release();
    53         mDepthStencil = NULL;
    54     }
    56     if (mRenderTarget)
    57     {
    58         mRenderTarget->Release();
    59         mRenderTarget = NULL;
    60     }
    62     if (mOffscreenTexture)
    63     {
    64         mOffscreenTexture->Release();
    65         mOffscreenTexture = NULL;
    66     }
    68     if (mWindow)
    69         mShareHandle = NULL;
    70 }
    72 static DWORD convertInterval(EGLint interval)
    73 {
    74     switch(interval)
    75     {
    76       case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
    77       case 1: return D3DPRESENT_INTERVAL_ONE;
    78       case 2: return D3DPRESENT_INTERVAL_TWO;
    79       case 3: return D3DPRESENT_INTERVAL_THREE;
    80       case 4: return D3DPRESENT_INTERVAL_FOUR;
    81       default: UNREACHABLE();
    82     }
    84     return D3DPRESENT_INTERVAL_DEFAULT;
    85 }
    87 EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight)
    88 {
    89     // D3D9 does not support resizing swap chains without recreating them
    90     return reset(backbufferWidth, backbufferHeight, mSwapInterval);
    91 }
    93 EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
    94 {
    95     IDirect3DDevice9 *device = mRenderer->getDevice();
    97     if (device == NULL)
    98     {
    99         return EGL_BAD_ACCESS;
   100     }
   102     // Evict all non-render target textures to system memory and release all resources
   103     // before reallocating them to free up as much video memory as possible.
   104     device->EvictManagedResources();
   106     HRESULT result;
   108     // Release specific resources to free up memory for the new render target, while the
   109     // old render target still exists for the purpose of preserving its contents.
   110     if (mSwapChain)
   111     {
   112         mSwapChain->Release();
   113         mSwapChain = NULL;
   114     }
   116     if (mBackBuffer)
   117     {
   118         mBackBuffer->Release();
   119         mBackBuffer = NULL;
   120     }
   122     if (mOffscreenTexture)
   123     {
   124         mOffscreenTexture->Release();
   125         mOffscreenTexture = NULL;
   126     }
   128     if (mDepthStencil)
   129     {
   130         mDepthStencil->Release();
   131         mDepthStencil = NULL;
   132     }
   134     HANDLE *pShareHandle = NULL;
   135     if (!mWindow && mRenderer->getShareHandleSupport())
   136     {
   137         pShareHandle = &mShareHandle;
   138     }
   140     result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
   141                                    gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT,
   142                                    &mOffscreenTexture, pShareHandle);
   143     if (FAILED(result))
   144     {
   145         ERR("Could not create offscreen texture: %08lX", result);
   146         release();
   148         if (d3d9::isDeviceLostError(result))
   149         {
   150             return EGL_CONTEXT_LOST;
   151         }
   152         else
   153         {
   154             return EGL_BAD_ALLOC;
   155         }
   156     }
   158     IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
   160     result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
   161     ASSERT(SUCCEEDED(result));
   163     if (oldRenderTarget)
   164     {
   165         RECT rect =
   166         {
   167             0, 0,
   168             mWidth, mHeight
   169         };
   171         if (rect.right > static_cast<LONG>(backbufferWidth))
   172         {
   173             rect.right = backbufferWidth;
   174         }
   176         if (rect.bottom > static_cast<LONG>(backbufferHeight))
   177         {
   178             rect.bottom = backbufferHeight;
   179         }
   181         mRenderer->endScene();
   183         result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
   184         ASSERT(SUCCEEDED(result));
   186         oldRenderTarget->Release();
   187     }
   189     if (mWindow)
   190     {
   191         D3DPRESENT_PARAMETERS presentParameters = {0};
   192         presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat);
   193         presentParameters.BackBufferCount = 1;
   194         presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat);
   195         presentParameters.EnableAutoDepthStencil = FALSE;
   196         presentParameters.Flags = 0;
   197         presentParameters.hDeviceWindow = mWindow;
   198         presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
   199         presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
   200         presentParameters.PresentationInterval = convertInterval(swapInterval);
   201         presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
   202         presentParameters.Windowed = TRUE;
   203         presentParameters.BackBufferWidth = backbufferWidth;
   204         presentParameters.BackBufferHeight = backbufferHeight;
   206         // http://crbug.com/140239
   207         // http://crbug.com/143434
   208         //
   209         // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width
   210         // when using the integrated Intel. This rounds the width up rather than down.
   211         //
   212         // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID
   213         // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur.
   214         if (mRenderer->getAdapterVendor() == VENDOR_ID_INTEL)
   215         {
   216             presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
   217         }
   219         result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
   221         if (FAILED(result))
   222         {
   223             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
   225             ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
   226             release();
   228             if (d3d9::isDeviceLostError(result))
   229             {
   230                 return EGL_CONTEXT_LOST;
   231             }
   232             else
   233             {
   234                 return EGL_BAD_ALLOC;
   235             }
   236         }
   238         result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
   239         ASSERT(SUCCEEDED(result));
   240         InvalidateRect(mWindow, NULL, FALSE);
   241     }
   243     if (mDepthBufferFormat != GL_NONE)
   244     {
   245         result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
   246                                                    gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat),
   247                                                    D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL);
   249         if (FAILED(result))
   250         {
   251             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
   253             ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
   254             release();
   256             if (d3d9::isDeviceLostError(result))
   257             {
   258                 return EGL_CONTEXT_LOST;
   259             }
   260             else
   261             {
   262                 return EGL_BAD_ALLOC;
   263             }
   264         }
   265     }
   267     mWidth = backbufferWidth;
   268     mHeight = backbufferHeight;
   269     mSwapInterval = swapInterval;
   271     return EGL_SUCCESS;
   272 }
   274 // parameters should be validated/clamped by caller
   275 EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
   276 {
   277     if (!mSwapChain)
   278     {
   279         return EGL_SUCCESS;
   280     }
   282     IDirect3DDevice9 *device = mRenderer->getDevice();
   284     // Disable all pipeline operations
   285     device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
   286     device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
   287     device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
   288     device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
   289     device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
   290     device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
   291     device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
   292     device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
   293     device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
   294     device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
   295     device->SetPixelShader(NULL);
   296     device->SetVertexShader(NULL);
   298     device->SetRenderTarget(0, mBackBuffer);
   299     device->SetDepthStencilSurface(NULL);
   301     device->SetTexture(0, mOffscreenTexture);
   302     device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
   303     device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
   304     device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
   305     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
   306     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
   307     device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
   308     device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
   309     device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
   311     D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
   312     device->SetViewport(&viewport);
   314     float x1 = x - 0.5f;
   315     float y1 = (mHeight - y - height) - 0.5f;
   316     float x2 = (x + width) - 0.5f;
   317     float y2 = (mHeight - y) - 0.5f;
   319     float u1 = x / float(mWidth);
   320     float v1 = y / float(mHeight);
   321     float u2 = (x + width) / float(mWidth);
   322     float v2 = (y + height) / float(mHeight);
   324     float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
   325                         {x2, y1, 0.0f, 1.0f, u2, v2},
   326                         {x2, y2, 0.0f, 1.0f, u2, v1},
   327                         {x1, y2, 0.0f, 1.0f, u1, v1}};   // x, y, z, rhw, u, v
   329     mRenderer->startScene();
   330     device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
   331     mRenderer->endScene();
   333     device->SetTexture(0, NULL);
   335     RECT rect =
   336     {
   337         x, mHeight - y - height,
   338         x + width, mHeight - y
   339     };
   341     HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
   343     mRenderer->markAllStateDirty();
   345     if (d3d9::isDeviceLostError(result))
   346     {
   347         return EGL_CONTEXT_LOST;
   348     }
   350     if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
   351     {
   352         return EGL_BAD_ALLOC;
   353     }
   355     ASSERT(SUCCEEDED(result));
   357     return EGL_SUCCESS;
   358 }
   360 // Increments refcount on surface.
   361 // caller must Release() the returned surface
   362 IDirect3DSurface9 *SwapChain9::getRenderTarget()
   363 {
   364     if (mRenderTarget)
   365     {
   366         mRenderTarget->AddRef();
   367     }
   369     return mRenderTarget;
   370 }
   372 // Increments refcount on surface.
   373 // caller must Release() the returned surface
   374 IDirect3DSurface9 *SwapChain9::getDepthStencil()
   375 {
   376     if (mDepthStencil)
   377     {
   378         mDepthStencil->AddRef();
   379     }
   381     return mDepthStencil;
   382 }
   384 // Increments refcount on texture.
   385 // caller must Release() the returned texture
   386 IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
   387 {
   388     if (mOffscreenTexture)
   389     {
   390         mOffscreenTexture->AddRef();
   391     }
   393     return mOffscreenTexture;
   394 }
   396 SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
   397 {
   398     ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain));
   399     return static_cast<rx::SwapChain9*>(swapChain);
   400 }
   402 void SwapChain9::recreate()
   403 {
   404     if (!mSwapChain)
   405     {
   406         return;
   407     }
   409     IDirect3DDevice9 *device = mRenderer->getDevice();
   410     if (device == NULL)
   411     {
   412         return;
   413     }
   415     D3DPRESENT_PARAMETERS presentParameters;
   416     HRESULT result = mSwapChain->GetPresentParameters(&presentParameters);
   417     ASSERT(SUCCEEDED(result));
   419     IDirect3DSwapChain9* newSwapChain = NULL;
   420     result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain);
   421     if (FAILED(result))
   422     {
   423         return;
   424     }
   426     mSwapChain->Release();
   427     mSwapChain = newSwapChain;
   429     mBackBuffer->Release();
   430     result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
   431     ASSERT(SUCCEEDED(result));
   432 }
   434 }

mercurial