1 // 2 // Copyright (c) 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 // StreamProducerNV12.cpp: Implements the stream producer for NV12 textures 8 9 #include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.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 namespace rx 16 { 17 StreamProducerNV12(Renderer11 * renderer)18StreamProducerNV12::StreamProducerNV12(Renderer11 *renderer) 19 : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mTextureWidth(0), mTextureHeight(0) 20 { 21 } 22 ~StreamProducerNV12()23StreamProducerNV12::~StreamProducerNV12() 24 { 25 SafeRelease(mTexture); 26 } 27 validateD3DNV12Texture(void * pointer) const28egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer) const 29 { 30 ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer); 31 32 // Check that the texture originated from our device 33 ID3D11Device *device; 34 textureD3D->GetDevice(&device); 35 if (device != mRenderer->getDevice()) 36 { 37 return egl::EglBadParameter() << "Texture not created on ANGLE D3D device"; 38 } 39 40 // Get the description and validate it 41 D3D11_TEXTURE2D_DESC desc; 42 textureD3D->GetDesc(&desc); 43 if (desc.Format != DXGI_FORMAT_NV12) 44 { 45 return egl::EglBadParameter() << "Texture format not DXGI_FORMAT_NV12"; 46 } 47 if (desc.Width < 1 || desc.Height < 1) 48 { 49 return egl::EglBadParameter() << "Texture is of size 0"; 50 } 51 if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0) 52 { 53 return egl::EglBadParameter() << "Texture dimensions are not even"; 54 } 55 return egl::NoError(); 56 } 57 postD3DNV12Texture(void * pointer,const egl::AttributeMap & attributes)58void StreamProducerNV12::postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) 59 { 60 ASSERT(pointer != nullptr); 61 ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer); 62 63 // Check that the texture originated from our device 64 ID3D11Device *device; 65 textureD3D->GetDevice(&device); 66 67 // Get the description 68 D3D11_TEXTURE2D_DESC desc; 69 textureD3D->GetDesc(&desc); 70 71 // Release the previous texture if there is one 72 SafeRelease(mTexture); 73 74 mTexture = textureD3D; 75 mTexture->AddRef(); 76 mTextureWidth = desc.Width; 77 mTextureHeight = desc.Height; 78 mArraySlice = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0)); 79 } 80 getGLFrameDescription(int planeIndex)81egl::Stream::GLTextureDescription StreamProducerNV12::getGLFrameDescription(int planeIndex) 82 { 83 // The UV plane of NV12 textures has half the width/height of the Y plane 84 egl::Stream::GLTextureDescription desc; 85 desc.width = (planeIndex == 0) ? mTextureWidth : (mTextureWidth / 2); 86 desc.height = (planeIndex == 0) ? mTextureHeight : (mTextureHeight / 2); 87 desc.internalFormat = (planeIndex == 0) ? GL_R8 : GL_RG8; 88 desc.mipLevels = 0; 89 return desc; 90 } 91 getD3DTexture()92ID3D11Texture2D *StreamProducerNV12::getD3DTexture() 93 { 94 return mTexture; 95 } 96 getArraySlice()97UINT StreamProducerNV12::getArraySlice() 98 { 99 return mArraySlice; 100 } 101 102 } // namespace rx 103