gfx/angle/src/libGLESv2/renderer/Blit.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) 2002-2010 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 // Blit.cpp: Surface copy utility class.
    10 #include "libGLESv2/renderer/Blit.h"
    12 #include "libGLESv2/main.h"
    13 #include "libGLESv2/renderer/renderer9_utils.h"
    14 #include "libGLESv2/renderer/TextureStorage9.h"
    15 #include "libGLESv2/renderer/RenderTarget9.h"
    16 #include "libGLESv2/renderer/Renderer9.h"
    17 #include "libGLESv2/Framebuffer.h"
    18 #include "libGLESv2/Renderbuffer.h"
    20 namespace
    21 {
    22 #include "libGLESv2/renderer/shaders/compiled/standardvs.h"
    23 #include "libGLESv2/renderer/shaders/compiled/flipyvs.h"
    24 #include "libGLESv2/renderer/shaders/compiled/passthroughps.h"
    25 #include "libGLESv2/renderer/shaders/compiled/luminanceps.h"
    26 #include "libGLESv2/renderer/shaders/compiled/componentmaskps.h"
    28 const BYTE* const g_shaderCode[] =
    29 {
    30     g_vs20_standardvs,
    31     g_vs20_flipyvs,
    32     g_ps20_passthroughps,
    33     g_ps20_luminanceps,
    34     g_ps20_componentmaskps
    35 };
    37 const size_t g_shaderSize[] =
    38 {
    39     sizeof(g_vs20_standardvs),
    40     sizeof(g_vs20_flipyvs),
    41     sizeof(g_ps20_passthroughps),
    42     sizeof(g_ps20_luminanceps),
    43     sizeof(g_ps20_componentmaskps)
    44 };
    45 }
    47 namespace rx
    48 {
    49 Blit::Blit(rx::Renderer9 *renderer)
    50   : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL)
    51 {
    52     initGeometry();
    53     memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
    54 }
    56 Blit::~Blit()
    57 {
    58     if (mSavedStateBlock) mSavedStateBlock->Release();
    59     if (mQuadVertexBuffer) mQuadVertexBuffer->Release();
    60     if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release();
    62     for (int i = 0; i < SHADER_COUNT; i++)
    63     {
    64         if (mCompiledShaders[i])
    65         {
    66             mCompiledShaders[i]->Release();
    67         }
    68     }
    69 }
    71 void Blit::initGeometry()
    72 {
    73     static const float quad[] =
    74     {
    75         -1, -1,
    76         -1,  1,
    77          1, -1,
    78          1,  1
    79     };
    81     IDirect3DDevice9 *device = mRenderer->getDevice();
    83     HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
    85     if (FAILED(result))
    86     {
    87         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
    88         return gl::error(GL_OUT_OF_MEMORY);
    89     }
    91     void *lockPtr = NULL;
    92     result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
    94     if (FAILED(result) || lockPtr == NULL)
    95     {
    96         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
    97         return gl::error(GL_OUT_OF_MEMORY);
    98     }
   100     memcpy(lockPtr, quad, sizeof(quad));
   101     mQuadVertexBuffer->Unlock();
   103     static const D3DVERTEXELEMENT9 elements[] =
   104     {
   105         { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
   106         D3DDECL_END()
   107     };
   109     result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
   111     if (FAILED(result))
   112     {
   113         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
   114         return gl::error(GL_OUT_OF_MEMORY);
   115     }
   116 }
   118 template <class D3DShaderType>
   119 bool Blit::setShader(ShaderId source, const char *profile,
   120                      D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length),
   121                      HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
   122 {
   123     IDirect3DDevice9 *device = mRenderer->getDevice();
   125     D3DShaderType *shader;
   127     if (mCompiledShaders[source] != NULL)
   128     {
   129         shader = static_cast<D3DShaderType*>(mCompiledShaders[source]);
   130     }
   131     else
   132     {
   133         const BYTE* shaderCode = g_shaderCode[source];
   134         size_t shaderSize = g_shaderSize[source];
   136         shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
   137         if (!shader)
   138         {
   139             ERR("Failed to create shader for blit operation");
   140             return false;
   141         }
   143         mCompiledShaders[source] = shader;
   144     }
   146     HRESULT hr = (device->*setShader)(shader);
   148     if (FAILED(hr))
   149     {
   150         ERR("Failed to set shader for blit operation");
   151         return false;
   152     }
   154     return true;
   155 }
   157 bool Blit::setVertexShader(ShaderId shader)
   158 {
   159     return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
   160 }
   162 bool Blit::setPixelShader(ShaderId shader)
   163 {
   164     return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
   165 }
   167 RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
   168 {
   169     D3DSURFACE_DESC desc;
   170     surface->GetDesc(&desc);
   172     RECT rect;
   173     rect.left = 0;
   174     rect.top = 0;
   175     rect.right = desc.Width;
   176     rect.bottom = desc.Height;
   178     return rect;
   179 }
   181 bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
   182 {
   183     IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
   184     if (!texture)
   185     {
   186         return false;
   187     }
   189     IDirect3DDevice9 *device = mRenderer->getDevice();
   191     saveState();
   193     device->SetTexture(0, texture);
   194     device->SetRenderTarget(0, dest);
   196     setVertexShader(SHADER_VS_STANDARD);
   197     setPixelShader(SHADER_PS_PASSTHROUGH);
   199     setCommonBlitState();
   200     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   201     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   203     setViewport(getSurfaceRect(dest), 0, 0);
   205     render();
   207     texture->Release();
   209     restoreState();
   211     return true;
   212 }
   214 bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
   215 {
   216     RenderTarget9 *renderTarget = NULL;
   217     IDirect3DSurface9 *source = NULL;
   218     gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
   220     if (colorbuffer)
   221     {
   222         renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
   223     }
   225     if (renderTarget)
   226     {
   227         source = renderTarget->getSurface();
   228     }
   230     if (!source)
   231     {
   232         ERR("Failed to retrieve the render target.");
   233         return gl::error(GL_OUT_OF_MEMORY, false);
   234     }
   236     TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
   237     IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
   238     bool result = false;
   240     if (destSurface)
   241     {
   242         result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
   243         destSurface->Release();
   244     }
   246     source->Release();
   247     return result;
   248 }
   250 bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
   251 {
   252     RenderTarget9 *renderTarget = NULL;
   253     IDirect3DSurface9 *source = NULL;
   254     gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
   256     if (colorbuffer)
   257     {
   258         renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
   259     }
   261     if (renderTarget)
   262     {
   263         source = renderTarget->getSurface();
   264     }
   266     if (!source)
   267     {
   268         ERR("Failed to retrieve the render target.");
   269         return gl::error(GL_OUT_OF_MEMORY, false);
   270     }
   272     TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
   273     IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
   274     bool result = false;
   276     if (destSurface)
   277     {
   278         result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
   279         destSurface->Release();
   280     }
   282     source->Release();
   283     return result;
   284 }
   286 bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
   287 {
   288     if (!dest)
   289     {
   290         return false;
   291     }
   293     IDirect3DDevice9 *device = mRenderer->getDevice();
   295     D3DSURFACE_DESC sourceDesc;
   296     D3DSURFACE_DESC destDesc;
   297     source->GetDesc(&sourceDesc);
   298     dest->GetDesc(&destDesc);
   300     if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
   301         d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat))   // Can use StretchRect
   302     {
   303         RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
   304         HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
   306         if (FAILED(result))
   307         {
   308             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
   309             return gl::error(GL_OUT_OF_MEMORY, false);
   310         }
   311     }
   312     else
   313     {
   314         return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
   315     }
   316     return true;
   317 }
   319 bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
   320 {
   321     IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
   322     if (!texture)
   323     {
   324         return false;
   325     }
   327     IDirect3DDevice9 *device = mRenderer->getDevice();
   329     saveState();
   331     device->SetTexture(0, texture);
   332     device->SetRenderTarget(0, dest);
   334     setViewport(sourceRect, xoffset, yoffset);
   336     setCommonBlitState();
   337     if (setFormatConvertShaders(destFormat))
   338     {
   339         render();
   340     }
   342     texture->Release();
   344     restoreState();
   346     return true;
   347 }
   349 bool Blit::setFormatConvertShaders(GLenum destFormat)
   350 {
   351     bool okay = setVertexShader(SHADER_VS_STANDARD);
   353     switch (destFormat)
   354     {
   355       default: UNREACHABLE();
   356       case GL_RGBA:
   357       case GL_BGRA_EXT:
   358       case GL_RGB:
   359       case GL_ALPHA:
   360         okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
   361         break;
   363       case GL_LUMINANCE:
   364       case GL_LUMINANCE_ALPHA:
   365         okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
   366         break;
   367     }
   369     if (!okay)
   370     {
   371         return false;
   372     }
   374     enum { X = 0, Y = 1, Z = 2, W = 3 };
   376     // The meaning of this constant depends on the shader that was selected.
   377     // See the shader assembly code above for details.
   378     float psConst0[4] = { 0, 0, 0, 0 };
   380     switch (destFormat)
   381     {
   382       default: UNREACHABLE();
   383       case GL_RGBA:
   384       case GL_BGRA_EXT:
   385         psConst0[X] = 1;
   386         psConst0[Z] = 1;
   387         break;
   389       case GL_RGB:
   390         psConst0[X] = 1;
   391         psConst0[W] = 1;
   392         break;
   394       case GL_ALPHA:
   395         psConst0[Z] = 1;
   396         break;
   398       case GL_LUMINANCE:
   399         psConst0[Y] = 1;
   400         break;
   402       case GL_LUMINANCE_ALPHA:
   403         psConst0[X] = 1;
   404         break;
   405     }
   407     mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1);
   409     return true;
   410 }
   412 IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
   413 {
   414     if (!surface)
   415     {
   416         return NULL;
   417     }
   419     IDirect3DDevice9 *device = mRenderer->getDevice();
   421     D3DSURFACE_DESC sourceDesc;
   422     surface->GetDesc(&sourceDesc);
   424     // Copy the render target into a texture
   425     IDirect3DTexture9 *texture;
   426     HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL);
   428     if (FAILED(result))
   429     {
   430         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
   431         return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
   432     }
   434     IDirect3DSurface9 *textureSurface;
   435     result = texture->GetSurfaceLevel(0, &textureSurface);
   437     if (FAILED(result))
   438     {
   439         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
   440         texture->Release();
   441         return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
   442     }
   444     mRenderer->endScene();
   445     result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
   447     textureSurface->Release();
   449     if (FAILED(result))
   450     {
   451         ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
   452         texture->Release();
   453         return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
   454     }
   456     return texture;
   457 }
   459 void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
   460 {
   461     IDirect3DDevice9 *device = mRenderer->getDevice();
   463     D3DVIEWPORT9 vp;
   464     vp.X      = xoffset;
   465     vp.Y      = yoffset;
   466     vp.Width  = sourceRect.right - sourceRect.left;
   467     vp.Height = sourceRect.bottom - sourceRect.top;
   468     vp.MinZ   = 0.0f;
   469     vp.MaxZ   = 1.0f;
   470     device->SetViewport(&vp);
   472     float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
   473     device->SetVertexShaderConstantF(0, halfPixelAdjust, 1);
   474 }
   476 void Blit::setCommonBlitState()
   477 {
   478     IDirect3DDevice9 *device = mRenderer->getDevice();
   480     device->SetDepthStencilSurface(NULL);
   482     device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
   483     device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
   484     device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
   485     device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
   486     device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
   487     device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
   488     device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
   489     device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
   491     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
   492     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
   493     device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
   494     device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
   495     device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
   497     RECT scissorRect = {0};   // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
   498     device->SetScissorRect(&scissorRect);
   500     for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
   501     {
   502         device->SetStreamSourceFreq(i, 1);
   503     }
   504 }
   506 void Blit::render()
   507 {
   508     IDirect3DDevice9 *device = mRenderer->getDevice();
   510     HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
   511     hr = device->SetVertexDeclaration(mQuadVertexDeclaration);
   513     mRenderer->startScene();
   514     hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
   515 }
   517 void Blit::saveState()
   518 {
   519     IDirect3DDevice9 *device = mRenderer->getDevice();
   521     HRESULT hr;
   523     device->GetDepthStencilSurface(&mSavedDepthStencil);
   524     device->GetRenderTarget(0, &mSavedRenderTarget);
   526     if (mSavedStateBlock == NULL)
   527     {
   528         hr = device->BeginStateBlock();
   529         ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
   531         setCommonBlitState();
   533         static const float dummyConst[4] = { 0, 0, 0, 0 };
   535         device->SetVertexShader(NULL);
   536         device->SetVertexShaderConstantF(0, dummyConst, 1);
   537         device->SetPixelShader(NULL);
   538         device->SetPixelShaderConstantF(0, dummyConst, 1);
   540         D3DVIEWPORT9 dummyVp;
   541         dummyVp.X = 0;
   542         dummyVp.Y = 0;
   543         dummyVp.Width = 1;
   544         dummyVp.Height = 1;
   545         dummyVp.MinZ = 0;
   546         dummyVp.MaxZ = 1;
   548         device->SetViewport(&dummyVp);
   550         device->SetTexture(0, NULL);
   552         device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
   554         device->SetVertexDeclaration(mQuadVertexDeclaration);
   556         hr = device->EndStateBlock(&mSavedStateBlock);
   557         ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
   558     }
   560     ASSERT(mSavedStateBlock != NULL);
   562     if (mSavedStateBlock != NULL)
   563     {
   564         hr = mSavedStateBlock->Capture();
   565         ASSERT(SUCCEEDED(hr));
   566     }
   567 }
   569 void Blit::restoreState()
   570 {
   571     IDirect3DDevice9 *device = mRenderer->getDevice();
   573     device->SetDepthStencilSurface(mSavedDepthStencil);
   574     if (mSavedDepthStencil != NULL)
   575     {
   576         mSavedDepthStencil->Release();
   577         mSavedDepthStencil = NULL;
   578     }
   580     device->SetRenderTarget(0, mSavedRenderTarget);
   581     if (mSavedRenderTarget != NULL)
   582     {
   583         mSavedRenderTarget->Release();
   584         mSavedRenderTarget = NULL;
   585     }
   587     ASSERT(mSavedStateBlock != NULL);
   589     if (mSavedStateBlock != NULL)
   590     {
   591         mSavedStateBlock->Apply();
   592     }
   593 }
   595 }

mercurial