Hash :
bda75597
Author :
Date :
2016-04-18T17:25:54
Finish NV12 support via streams. The main functionality for NV12 texture support through EGL streams has been added. Updates to the compiler, texture code, and stream code were added to support binding to external D3D11 NV12 textures. An end2end test was also added to test sampling of YUV textures and converting to RGB. There is also a new script to convert BMP files to an NV12 texture ready to load into D3D11 for testing purposes. BUG=angleproject:1332 Change-Id: I39b6ec393ea338e2c843fb911acc1b36cd1158a0 Reviewed-on: https://chromium-review.googlesource.com/339454 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Ian Ewell <ewell@google.com> Reviewed-on: https://chromium-review.googlesource.com/341254 Reviewed-by: Ian Ewell <ewell@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
//
// 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<ID3D11Texture2D *>(pointer);
// Check that the texture originated from our device
ID3D11Device *device;
textureD3D->GetDevice(&device);
if (device != mRenderer->getDevice())
{
return egl::Error(EGL_BAD_PARAMETER, "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::Error(EGL_BAD_PARAMETER, "Texture format not DXGI_FORMAT_NV12");
}
if (desc.Width < 1 || desc.Height < 1)
{
return egl::Error(EGL_BAD_PARAMETER, "Texture is of size 0");
}
if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
{
return egl::Error(EGL_BAD_PARAMETER, "Texture dimensions are not even");
}
return egl::Error(EGL_SUCCESS);
}
void StreamProducerNV12::postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes)
{
ASSERT(pointer != nullptr);
ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(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<UINT>(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