tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StreamProducerD3DTexture.cpp (4968B)


      1 //
      2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // StreamProducerD3DTexture.cpp: Implements the stream producer for D3D11 textures
      8 
      9 #include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
     10 
     11 #include "common/utilities.h"
     12 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
     13 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
     14 
     15 #include <array>
     16 
     17 namespace rx
     18 {
     19 
     20 namespace
     21 {
     22 
     23 egl::Error GetGLDescFromTex(ID3D11Texture2D *const tex,
     24                            const UINT planeIndex,
     25                            egl::Stream::GLTextureDescription *const out)
     26 {
     27    if (!tex)
     28        return egl::EglBadParameter() << "Texture is null";
     29 
     30    D3D11_TEXTURE2D_DESC desc;
     31    tex->GetDesc(&desc);
     32 
     33    if (desc.Width < 1 || desc.Height < 1)
     34        return egl::EglBadParameter() << "Width or height < 1";
     35 
     36    out->width     = desc.Width;
     37    out->height    = desc.Height;
     38    out->mipLevels = 0;
     39 
     40    std::array<uint32_t, 2> planeFormats = {};
     41    switch (desc.Format)
     42    {
     43        case DXGI_FORMAT_NV12:
     44            planeFormats = {GL_R8, GL_RG8};
     45            break;
     46 
     47        case DXGI_FORMAT_P010:
     48        case DXGI_FORMAT_P016:
     49            planeFormats = {GL_R16_EXT, GL_RG16_EXT};
     50            break;
     51 
     52        case DXGI_FORMAT_R8_UNORM:
     53            planeFormats = {GL_R8};
     54            break;
     55        case DXGI_FORMAT_R8G8_UNORM:
     56            planeFormats[0] = GL_RG8;
     57            break;
     58        case DXGI_FORMAT_R8G8B8A8_UNORM:
     59            planeFormats[0] = GL_RGBA8;
     60            break;
     61        case DXGI_FORMAT_B8G8R8A8_UNORM:
     62            planeFormats[0] = GL_BGRA8_EXT;
     63            break;
     64 
     65        case DXGI_FORMAT_R16_UNORM:
     66            planeFormats[0] = GL_R16_EXT;
     67            break;
     68        case DXGI_FORMAT_R16G16_UNORM:
     69            planeFormats[0] = GL_RG16_EXT;
     70            break;
     71        case DXGI_FORMAT_R16G16B16A16_UNORM:
     72            planeFormats[0] = GL_RGBA16_EXT;
     73            break;
     74        case DXGI_FORMAT_R16G16B16A16_FLOAT:
     75            planeFormats[0] = GL_RGBA16F;
     76            break;
     77 
     78        default:
     79            return egl::EglBadParameter() << "Unsupported format";
     80    }
     81 
     82    if (planeFormats[1])  // If we have YUV planes, expect 4:2:0.
     83    {
     84        if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
     85            return egl::EglBadParameter() << "YUV 4:2:0 textures must have even width and height.";
     86    }
     87    if (planeIndex > 0)
     88    {
     89        out->width /= 2;
     90        out->height /= 2;
     91    }
     92 
     93    out->internalFormat = 0;
     94    if (planeIndex < planeFormats.size())
     95    {
     96        out->internalFormat = planeFormats[planeIndex];
     97    }
     98    if (!out->internalFormat)
     99        return egl::EglBadParameter() << "Plane out of range";
    100 
    101    return egl::NoError();
    102 }
    103 
    104 }  // namespace
    105 
    106 StreamProducerD3DTexture::StreamProducerD3DTexture(Renderer11 *renderer)
    107    : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mPlaneOffset(0)
    108 {}
    109 
    110 StreamProducerD3DTexture::~StreamProducerD3DTexture()
    111 {
    112    SafeRelease(mTexture);
    113 }
    114 
    115 egl::Error StreamProducerD3DTexture::validateD3DTexture(const void *pointer,
    116                                                        const egl::AttributeMap &attributes) const
    117 {
    118    // We must remove the const qualifier because "GetDevice" and "GetDesc" are non-const in D3D11.
    119    ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(const_cast<void *>(pointer));
    120 
    121    // Check that the texture originated from our device
    122    angle::ComPtr<ID3D11Device> device;
    123    textureD3D->GetDevice(&device);
    124    if (device.Get() != mRenderer->getDevice())
    125    {
    126        return egl::EglBadParameter() << "Texture not created on ANGLE D3D device";
    127    }
    128 
    129    const auto planeId = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
    130    egl::Stream::GLTextureDescription unused;
    131    return GetGLDescFromTex(textureD3D, planeId, &unused);
    132 }
    133 
    134 void StreamProducerD3DTexture::postD3DTexture(void *pointer, const egl::AttributeMap &attributes)
    135 {
    136    ASSERT(pointer != nullptr);
    137    ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
    138 
    139    // Release the previous texture if there is one
    140    SafeRelease(mTexture);
    141 
    142    mTexture = textureD3D;
    143    mTexture->AddRef();
    144    mPlaneOffset = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
    145    mArraySlice  = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0));
    146 }
    147 
    148 egl::Stream::GLTextureDescription StreamProducerD3DTexture::getGLFrameDescription(int planeIndex)
    149 {
    150    const auto planeOffsetIndex = static_cast<UINT>(planeIndex + mPlaneOffset);
    151    egl::Stream::GLTextureDescription ret;
    152    ANGLE_SWALLOW_ERR(GetGLDescFromTex(mTexture, planeOffsetIndex, &ret));
    153    return ret;
    154 }
    155 
    156 ID3D11Texture2D *StreamProducerD3DTexture::getD3DTexture()
    157 {
    158    return mTexture;
    159 }
    160 
    161 UINT StreamProducerD3DTexture::getArraySlice()
    162 {
    163    return mArraySlice;
    164 }
    165 
    166 }  // namespace rx