gfx/angle/src/libGLESv2/renderer/Image11.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 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 // Image11.h: Implements the rx::Image11 class, which acts as the interface to
     9 // the actual underlying resources of a Texture
    11 #include "libGLESv2/renderer/Renderer11.h"
    12 #include "libGLESv2/renderer/Image11.h"
    13 #include "libGLESv2/renderer/TextureStorage11.h"
    14 #include "libGLESv2/Framebuffer.h"
    15 #include "libGLESv2/Renderbuffer.h"
    17 #include "libGLESv2/main.h"
    18 #include "libGLESv2/utilities.h"
    19 #include "libGLESv2/renderer/renderer11_utils.h"
    20 #include "libGLESv2/renderer/generatemip.h"
    22 namespace rx
    23 {
    25 Image11::Image11()
    26 {
    27     mStagingTexture = NULL;
    28     mRenderer = NULL;
    29     mDXGIFormat = DXGI_FORMAT_UNKNOWN;
    30 }
    32 Image11::~Image11()
    33 {
    34     if (mStagingTexture)
    35     {
    36         mStagingTexture->Release();
    37     }
    38 }
    40 Image11 *Image11::makeImage11(Image *img)
    41 {
    42     ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
    43     return static_cast<rx::Image11*>(img);
    44 }
    46 void Image11::generateMipmap(Image11 *dest, Image11 *src)
    47 {
    48     ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
    49     ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
    50     ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
    52     D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped;
    53     dest->map(&destMapped);
    54     src->map(&srcMapped);
    56     const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData);
    57     unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData);
    59     if (sourceData && destData)
    60     {
    61         switch (src->getDXGIFormat())
    62         {
    63           case DXGI_FORMAT_R8G8B8A8_UNORM:
    64           case DXGI_FORMAT_B8G8R8A8_UNORM:
    65             GenerateMip<R8G8B8A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    66             break;
    67           case DXGI_FORMAT_A8_UNORM:
    68             GenerateMip<A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    69             break;
    70           case DXGI_FORMAT_R8_UNORM:
    71             GenerateMip<R8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    72             break;
    73           case DXGI_FORMAT_R32G32B32A32_FLOAT:
    74             GenerateMip<A32B32G32R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    75             break;
    76           case DXGI_FORMAT_R32G32B32_FLOAT:
    77             GenerateMip<R32G32B32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    78             break;
    79           case DXGI_FORMAT_R16G16B16A16_FLOAT:
    80             GenerateMip<A16B16G16R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    81             break;
    82           case DXGI_FORMAT_R8G8_UNORM:
    83             GenerateMip<R8G8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    84             break;
    85           case DXGI_FORMAT_R16_FLOAT:
    86             GenerateMip<R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    87             break;
    88           case DXGI_FORMAT_R16G16_FLOAT:
    89             GenerateMip<R16G16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    90             break;
    91           case DXGI_FORMAT_R32_FLOAT:
    92             GenerateMip<R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    93             break;
    94           case DXGI_FORMAT_R32G32_FLOAT:
    95             GenerateMip<R32G32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
    96             break;
    97           default:
    98             UNREACHABLE();
    99             break;
   100         }
   102         dest->unmap();
   103         src->unmap();
   104     }
   106     dest->markDirty();
   107 }
   109 bool Image11::isDirty() const
   110 {
   111     return (mStagingTexture && mDirty);
   112 }
   114 bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
   115 {
   116     TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
   117     return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height);
   118 }
   120 bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
   121 {
   122     TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
   123     return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height);
   124 }
   126 bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
   127 {
   128     if (mWidth != width ||
   129         mHeight != height ||
   130         mInternalFormat != internalformat ||
   131         forceRelease)
   132     {
   133         mRenderer = Renderer11::makeRenderer11(renderer);
   135         mWidth = width;
   136         mHeight = height;
   137         mInternalFormat = internalformat;
   138         // compute the d3d format that will be used
   139         mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
   140         mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
   142         if (mStagingTexture)
   143         {
   144             mStagingTexture->Release();
   145             mStagingTexture = NULL;
   146         }
   148         return true;
   149     }
   151     return false;
   152 }
   154 bool Image11::isRenderableFormat() const
   155 {
   156     return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat);
   157 }
   159 DXGI_FORMAT Image11::getDXGIFormat() const
   160 {
   161     // this should only happen if the image hasn't been redefined first
   162     // which would be a bug by the caller
   163     ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
   165     return mDXGIFormat;
   166 }
   168 // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
   169 // into the target pixel rectangle.
   170 void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
   171                        GLint unpackAlignment, const void *input)
   172 {
   173     D3D11_MAPPED_SUBRESOURCE mappedImage;
   174     HRESULT result = map(&mappedImage);
   175     if (FAILED(result))
   176     {
   177         ERR("Could not map image for loading.");
   178         return;
   179     }
   181     GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment);
   182     size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8;
   183     void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize));
   185     switch (mInternalFormat)
   186     {
   187       case GL_ALPHA8_EXT:
   188         loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   189         break;
   190       case GL_LUMINANCE8_EXT:
   191         loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
   192         break;
   193       case GL_ALPHA32F_EXT:
   194         loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   195         break;
   196       case GL_LUMINANCE32F_EXT:
   197         loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   198         break;
   199       case GL_ALPHA16F_EXT:
   200         loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   201         break;
   202       case GL_LUMINANCE16F_EXT:
   203         loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   204         break;
   205       case GL_LUMINANCE8_ALPHA8_EXT:
   206         loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
   207         break;
   208       case GL_LUMINANCE_ALPHA32F_EXT:
   209         loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   210         break;
   211       case GL_LUMINANCE_ALPHA16F_EXT:
   212         loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   213         break;
   214       case GL_RGB8_OES:
   215         loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   216         break;
   217       case GL_RGB565:
   218         loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   219         break;
   220       case GL_RGBA8_OES:
   221         loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   222         break;
   223       case GL_RGBA4:
   224         loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   225         break;
   226       case GL_RGB5_A1:
   227         loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   228         break;
   229       case GL_BGRA8_EXT:
   230         loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   231         break;
   232       case GL_RGB32F_EXT:
   233         loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   234         break;
   235       case GL_RGB16F_EXT:
   236         loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   237         break;
   238       case GL_RGBA32F_EXT:
   239         loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   240         break;
   241       case GL_RGBA16F_EXT:
   242         loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
   243         break;
   244       default: UNREACHABLE(); 
   245     }
   247     unmap();
   248 }
   250 void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
   251                                 const void *input)
   252 {
   253     ASSERT(xoffset % 4 == 0);
   254     ASSERT(yoffset % 4 == 0);
   256     D3D11_MAPPED_SUBRESOURCE mappedImage;
   257     HRESULT result = map(&mappedImage);
   258     if (FAILED(result))
   259     {
   260         ERR("Could not map image for loading.");
   261         return;
   262     }
   264     // Size computation assumes a 4x4 block compressed texture format
   265     size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8;
   266     void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize));
   268     GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat);
   269     GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat);
   270     int rows = inputSize / inputPitch;
   271     for (int i = 0; i < rows; ++i)
   272     {
   273         memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
   274     }
   276     unmap();
   277 }
   279 void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
   280 {
   281     gl::Renderbuffer *colorbuffer = source->getReadColorbuffer();
   283     if (colorbuffer && colorbuffer->getActualFormat() == (GLuint)mActualFormat)
   284     {
   285         // No conversion needed-- use copyback fastpath
   286         ID3D11Texture2D *colorBufferTexture = NULL;
   287         unsigned int subresourceIndex = 0;
   289         if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
   290         {
   291             D3D11_TEXTURE2D_DESC textureDesc;
   292             colorBufferTexture->GetDesc(&textureDesc);
   294             ID3D11Device *device = mRenderer->getDevice();
   295             ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   297             ID3D11Texture2D* srcTex = NULL;
   298             if (textureDesc.SampleDesc.Count > 1)
   299             {
   300                 D3D11_TEXTURE2D_DESC resolveDesc;
   301                 resolveDesc.Width = textureDesc.Width;
   302                 resolveDesc.Height = textureDesc.Height;
   303                 resolveDesc.MipLevels = 1;
   304                 resolveDesc.ArraySize = 1;
   305                 resolveDesc.Format = textureDesc.Format;
   306                 resolveDesc.SampleDesc.Count = 1;
   307                 resolveDesc.SampleDesc.Quality = 0;
   308                 resolveDesc.Usage = D3D11_USAGE_DEFAULT;
   309                 resolveDesc.BindFlags = 0;
   310                 resolveDesc.CPUAccessFlags = 0;
   311                 resolveDesc.MiscFlags = 0;
   313                 HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
   314                 if (FAILED(result))
   315                 {
   316                     ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
   317                     return;
   318                 }
   320                 deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
   321                 subresourceIndex = 0;
   322             }
   323             else
   324             {
   325                 srcTex = colorBufferTexture;
   326                 srcTex->AddRef();
   327             }
   329             D3D11_BOX srcBox;
   330             srcBox.left = x;
   331             srcBox.right = x + width;
   332             srcBox.top = y;
   333             srcBox.bottom = y + height;
   334             srcBox.front = 0;
   335             srcBox.back = 1;
   337             deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox);
   339             srcTex->Release();
   340             colorBufferTexture->Release();
   341         }
   342     }
   343     else
   344     {
   345         // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
   346         D3D11_MAPPED_SUBRESOURCE mappedImage;
   347         HRESULT result = map(&mappedImage);
   349         // determine the offset coordinate into the destination buffer
   350         GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset;
   351         void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset;
   353         mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat), 
   354                               gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset);
   356         unmap();
   357     }
   358 }
   360 ID3D11Texture2D *Image11::getStagingTexture()
   361 {
   362     createStagingTexture();
   364     return mStagingTexture;
   365 }
   367 unsigned int Image11::getStagingSubresource()
   368 {
   369     createStagingTexture();
   371     return mStagingSubresource;
   372 }
   374 void Image11::createStagingTexture()
   375 {
   376     if (mStagingTexture)
   377     {
   378         return;
   379     }
   381     ID3D11Texture2D *newTexture = NULL;
   382     int lodOffset = 1;
   383     const DXGI_FORMAT dxgiFormat = getDXGIFormat();
   384     ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures
   386     if (mWidth != 0 && mHeight != 0)
   387     {
   388         GLsizei width = mWidth;
   389         GLsizei height = mHeight;
   391         // adjust size if needed for compressed textures
   392         gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset);
   393         ID3D11Device *device = mRenderer->getDevice();
   395         D3D11_TEXTURE2D_DESC desc;
   396         desc.Width = width;
   397         desc.Height = height;
   398         desc.MipLevels = lodOffset + 1;
   399         desc.ArraySize = 1;
   400         desc.Format = dxgiFormat;
   401         desc.SampleDesc.Count = 1;
   402         desc.SampleDesc.Quality = 0;
   403         desc.Usage = D3D11_USAGE_STAGING;
   404         desc.BindFlags = 0;
   405         desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
   406         desc.MiscFlags = 0;
   408         HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture);
   410         if (FAILED(result))
   411         {
   412             ASSERT(result == E_OUTOFMEMORY);
   413             ERR("Creating image failed.");
   414             return gl::error(GL_OUT_OF_MEMORY);
   415         }
   416     }
   418     mStagingTexture = newTexture;
   419     mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
   420     mDirty = false;
   421 }
   423 HRESULT Image11::map(D3D11_MAPPED_SUBRESOURCE *map)
   424 {
   425     createStagingTexture();
   427     HRESULT result = E_FAIL;
   429     if (mStagingTexture)
   430     {
   431         ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   432         result = deviceContext->Map(mStagingTexture, mStagingSubresource, D3D11_MAP_WRITE, 0, map);
   434         // this can fail if the device is removed (from TDR)
   435         if (d3d11::isDeviceLostError(result))
   436         {
   437             mRenderer->notifyDeviceLost();
   438         }
   439         else if (SUCCEEDED(result))
   440         {
   441             mDirty = true;
   442         }
   443     }
   445     return result;
   446 }
   448 void Image11::unmap()
   449 {
   450     if (mStagingTexture)
   451     {
   452         ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   453         deviceContext->Unmap(mStagingTexture, mStagingSubresource);
   454     }
   455 }
   457 }

mercurial