// // Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // StreamProducerNV12.cpp: Implements the stream producer for NV12 textures #include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h" #include "common/utilities.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace rx { StreamProducerNV12::StreamProducerNV12(Renderer11 *renderer) : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mTextureWidth(0), mTextureHeight(0) { } StreamProducerNV12::~StreamProducerNV12() { SafeRelease(mTexture); } egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer) const { ID3D11Texture2D *textureD3D = static_cast(pointer); // Check that the texture originated from our device ID3D11Device *device; textureD3D->GetDevice(&device); if (device != mRenderer->getDevice()) { return egl::EglBadParameter() << "Texture not created on ANGLE D3D device"; } // Get the description and validate it D3D11_TEXTURE2D_DESC desc; textureD3D->GetDesc(&desc); if (desc.Format != DXGI_FORMAT_NV12) { return egl::EglBadParameter() << "Texture format not DXGI_FORMAT_NV12"; } if (desc.Width < 1 || desc.Height < 1) { return egl::EglBadParameter() << "Texture is of size 0"; } if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0) { return egl::EglBadParameter() << "Texture dimensions are not even"; } return egl::NoError(); } void StreamProducerNV12::postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) { ASSERT(pointer != nullptr); ID3D11Texture2D *textureD3D = static_cast(pointer); // Check that the texture originated from our device ID3D11Device *device; textureD3D->GetDevice(&device); // Get the description D3D11_TEXTURE2D_DESC desc; textureD3D->GetDesc(&desc); // Release the previous texture if there is one SafeRelease(mTexture); mTexture = textureD3D; mTexture->AddRef(); mTextureWidth = desc.Width; mTextureHeight = desc.Height; mArraySlice = static_cast(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0)); } egl::Stream::GLTextureDescription StreamProducerNV12::getGLFrameDescription(int planeIndex) { // The UV plane of NV12 textures has half the width/height of the Y plane egl::Stream::GLTextureDescription desc; desc.width = (planeIndex == 0) ? mTextureWidth : (mTextureWidth / 2); desc.height = (planeIndex == 0) ? mTextureHeight : (mTextureHeight / 2); desc.internalFormat = (planeIndex == 0) ? GL_R8 : GL_RG8; desc.mipLevels = 0; return desc; } ID3D11Texture2D *StreamProducerNV12::getD3DTexture() { return mTexture; } UINT StreamProducerNV12::getArraySlice() { return mArraySlice; } } // namespace rx