Bug 546514 - Part 3: Add D3D10 layers code. r=vlad

This commit is contained in:
Bas Schouten 2010-10-01 00:53:49 +02:00
parent a5835235f9
commit 889fee7223
14 changed files with 9179 additions and 0 deletions

View File

@ -0,0 +1,273 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "CanvasLayerD3D10.h"
#include "gfxImageSurface.h"
#include "gfxWindowsSurface.h"
#include "gfxWindowsPlatform.h"
namespace mozilla {
namespace layers {
CanvasLayerD3D10::~CanvasLayerD3D10()
{
}
void
CanvasLayerD3D10::Initialize(const Data& aData)
{
NS_ASSERTION(mSurface == nsnull, "BasicCanvasLayer::Initialize called twice!");
if (aData.mSurface) {
mSurface = aData.mSurface;
NS_ASSERTION(aData.mGLContext == nsnull,
"CanvasLayer can't have both surface and GLContext");
mNeedsYFlip = PR_FALSE;
mDataIsPremultiplied = PR_TRUE;
} else if (aData.mGLContext) {
NS_ASSERTION(aData.mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
mGLContext = aData.mGLContext;
mCanvasFramebuffer = mGLContext->GetOffscreenFBO();
mDataIsPremultiplied = aData.mGLBufferIsPremultiplied;
mNeedsYFlip = PR_TRUE;
} else {
NS_ERROR("CanvasLayer created without mSurface or mGLContext?");
}
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
if (mSurface && mSurface->GetType() == gfxASurface::SurfaceTypeD2D) {
void *data = mSurface->GetData(&gKeyD3D10Texture);
if (data) {
mTexture = static_cast<ID3D10Texture2D*>(data);
mIsD2DTexture = true;
device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
return;
}
}
mIsD2DTexture = false;
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mBounds.width, mBounds.height, 1, 1);
desc.Usage = D3D10_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture));
if (FAILED(hr)) {
NS_WARNING("Failed to create texture for CanvasLayer!");
return;
}
device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
}
void
CanvasLayerD3D10::Updated(const nsIntRect& aRect)
{
if (mIsD2DTexture) {
mSurface->Flush();
return;
}
if (mGLContext) {
// WebGL reads entire surface.
D3D10_MAPPED_TEXTURE2D map;
HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map);
if (FAILED(hr)) {
NS_WARNING("Failed to map CanvasLayer texture.");
return;
}
PRUint8 *destination;
if (map.RowPitch != mBounds.width * 4) {
destination = new PRUint8[mBounds.width * mBounds.height * 4];
} else {
destination = (PRUint8*)map.pData;
}
// We have to flush to ensure that any buffered GL operations are
// in the framebuffer before we read.
mGLContext->fFlush();
PRUint32 currentFramebuffer = 0;
mGLContext->fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&currentFramebuffer);
// Make sure that we read pixels from the correct framebuffer, regardless
// of what's currently bound.
if (currentFramebuffer != mCanvasFramebuffer)
mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mCanvasFramebuffer);
// For simplicity, we read the entire framebuffer for now -- in
// the future we should use aRect, though with WebGL we don't
// have an easy way to generate one.
nsRefPtr<gfxImageSurface> tmpSurface =
new gfxImageSurface(destination,
gfxIntSize(mBounds.width, mBounds.height),
mBounds.width * 4,
gfxASurface::ImageFormatARGB32);
mGLContext->ReadPixelsIntoImageSurface(0, 0,
mBounds.width, mBounds.height,
tmpSurface);
tmpSurface = nsnull;
// Put back the previous framebuffer binding.
if (currentFramebuffer != mCanvasFramebuffer)
mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, currentFramebuffer);
if (map.RowPitch != mBounds.width * 4) {
for (int y = 0; y < mBounds.height; y++) {
memcpy((PRUint8*)map.pData + map.RowPitch * y,
destination + mBounds.width * 4 * y,
mBounds.width * 4);
}
delete [] destination;
}
mTexture->Unmap(0);
} else if (mSurface) {
RECT r;
r.left = aRect.x;
r.top = aRect.y;
r.right = aRect.XMost();
r.bottom = aRect.YMost();
D3D10_MAPPED_TEXTURE2D map;
HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map);
if (FAILED(hr)) {
NS_WARNING("Failed to lock CanvasLayer texture.");
return;
}
PRUint8 *startBits;
PRUint32 sourceStride;
nsRefPtr<gfxImageSurface> dstSurface;
dstSurface = new gfxImageSurface((unsigned char*)map.pData,
gfxIntSize(aRect.width, aRect.height),
map.RowPitch,
gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(dstSurface);
ctx->Translate(gfxPoint(-aRect.x, -aRect.y));
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(mSurface);
ctx->Paint();
mTexture->Unmap(0);
}
}
Layer*
CanvasLayerD3D10::GetLayer()
{
return this;
}
void
CanvasLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
{
if (!mTexture) {
return;
}
nsIntRect visibleRect = mVisibleRegion.GetBounds();
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity);
ID3D10EffectTechnique *technique;
if (mDataIsPremultiplied) {
if (mSurface && mSurface->GetContentType() == gfxASurface::CONTENT_COLOR) {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
}
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremul");
}
}
if (mSRView) {
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
}
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)mBounds.x,
(float)mBounds.y,
(float)mBounds.width,
(float)mBounds.height)
);
if (mNeedsYFlip) {
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
0,
1.0f,
1.0f,
-1.0f)
);
}
technique->GetPassByIndex(0)->Apply(0);
device()->Draw(4, 0);
if (mNeedsYFlip) {
effect()->GetVariableByName("vTextureCoords")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
}
}
} /* namespace layers */
} /* namespace mozilla */

View File

@ -0,0 +1,93 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_CANVASLAYEROGL_H
#define GFX_CANVASLAYEROGL_H
#include "LayerManagerD3D10.h"
#include "GLContext.h"
#include "gfxASurface.h"
namespace mozilla {
namespace layers {
class THEBES_API CanvasLayerD3D10 : public CanvasLayer,
public LayerD3D10
{
public:
CanvasLayerD3D10(LayerManagerD3D10 *aManager)
: CanvasLayer(aManager, NULL),
LayerD3D10(aManager),
mTexture(0),
mDataIsPremultiplied(PR_FALSE),
mNeedsYFlip(PR_FALSE)
{
mImplData = static_cast<LayerD3D10*>(this);
}
~CanvasLayerD3D10();
// CanvasLayer implementation
virtual void Initialize(const Data& aData);
virtual void Updated(const nsIntRect& aRect);
// LayerD3D10 implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
private:
typedef mozilla::gl::GLContext GLContext;
nsRefPtr<gfxASurface> mSurface;
nsRefPtr<GLContext> mGLContext;
PRUint32 mCanvasFramebuffer;
nsRefPtr<ID3D10Texture2D> mTexture;
nsRefPtr<ID3D10ShaderResourceView> mSRView;
nsIntRect mBounds;
PRPackedBool mDataIsPremultiplied;
PRPackedBool mNeedsYFlip;
PRPackedBool mIsD2DTexture;
};
} /* layers */
} /* mozilla */
#endif /* GFX_CANVASLAYERD3D10_H */

View File

@ -0,0 +1,93 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert O'Callahan <robert@ocallahan.org>
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ColorLayerD3D10.h"
namespace mozilla {
namespace layers {
ColorLayerD3D10::ColorLayerD3D10(LayerManagerD3D10 *aManager)
: ColorLayer(aManager, NULL)
, LayerD3D10(aManager)
{
mImplData = static_cast<LayerD3D10*>(this);
}
Layer*
ColorLayerD3D10::GetLayer()
{
return this;
}
void
ColorLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
{
float color[4];
// color is premultiplied, so we need to adjust all channels
color[0] = (float)(mColor.r * GetOpacity() * aOpacity);
color[1] = (float)(mColor.g * GetOpacity() * aOpacity);
color[2] = (float)(mColor.b * GetOpacity() * aOpacity);
color[3] = (float)(mColor.a * GetOpacity() * aOpacity);
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
ID3D10EffectTechnique *technique;
technique = effect()->GetTechniqueByName("RenderSolidColorLayer");
nsIntRegionRectIterator iter(mVisibleRegion);
const nsIntRect *iterRect;
while ((iterRect = iter.Next())) {
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)iterRect->x,
(float)iterRect->y,
(float)iterRect->width,
(float)iterRect->height)
);
technique->GetPassByIndex(0)->Apply(0);
device()->Draw(4, 0);
}
}
} /* layers */
} /* mozilla */

View File

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_COLORLAYERD3D10_H
#define GFX_COLORLAYERD3D10_H
#include "Layers.h"
#include "LayerManagerD3D10.h"
namespace mozilla {
namespace layers {
class ColorLayerD3D10 : public ColorLayer,
public LayerD3D10
{
public:
ColorLayerD3D10(LayerManagerD3D10 *aManager);
/* LayerD3D10 implementation */
Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
};
} /* layers */
} /* mozilla */
#endif /* GFX_THEBESLAYERD3D10_H */

View File

@ -0,0 +1,337 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ContainerLayerD3D10.h"
#include "nsAlgorithm.h"
namespace mozilla {
namespace layers {
ContainerLayerD3D10::ContainerLayerD3D10(LayerManagerD3D10 *aManager)
: ContainerLayer(aManager, NULL)
, LayerD3D10(aManager)
{
mImplData = static_cast<LayerD3D10*>(this);
}
ContainerLayerD3D10::~ContainerLayerD3D10()
{
while (mFirstChild) {
RemoveChild(mFirstChild);
}
}
void
ContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter)
{
aChild->SetParent(this);
if (!aAfter) {
Layer *oldFirstChild = GetFirstChild();
mFirstChild = aChild;
aChild->SetNextSibling(oldFirstChild);
aChild->SetPrevSibling(nsnull);
if (oldFirstChild) {
oldFirstChild->SetPrevSibling(aChild);
}
NS_ADDREF(aChild);
return;
}
for (Layer *child = GetFirstChild();
child; child = child->GetNextSibling()) {
if (aAfter == child) {
Layer *oldNextSibling = child->GetNextSibling();
child->SetNextSibling(aChild);
aChild->SetNextSibling(oldNextSibling);
if (oldNextSibling) {
oldNextSibling->SetPrevSibling(aChild);
}
aChild->SetPrevSibling(child);
NS_ADDREF(aChild);
return;
}
}
NS_WARNING("Failed to find aAfter layer!");
}
void
ContainerLayerD3D10::RemoveChild(Layer *aChild)
{
if (GetFirstChild() == aChild) {
mFirstChild = GetFirstChild()->GetNextSibling();
if (mFirstChild) {
mFirstChild->SetPrevSibling(nsnull);
}
aChild->SetNextSibling(nsnull);
aChild->SetPrevSibling(nsnull);
aChild->SetParent(nsnull);
NS_RELEASE(aChild);
return;
}
Layer *lastChild = nsnull;
for (Layer *child = GetFirstChild(); child;
child = child->GetNextSibling()) {
if (child == aChild) {
// We're sure this is not our first child. So lastChild != NULL.
lastChild->SetNextSibling(child->GetNextSibling());
if (child->GetNextSibling()) {
child->GetNextSibling()->SetPrevSibling(lastChild);
}
child->SetNextSibling(nsnull);
child->SetPrevSibling(nsnull);
child->SetParent(nsnull);
NS_RELEASE(aChild);
return;
}
lastChild = child;
}
}
Layer*
ContainerLayerD3D10::GetLayer()
{
return this;
}
LayerD3D10*
ContainerLayerD3D10::GetFirstChildD3D10()
{
if (!mFirstChild) {
return nsnull;
}
return static_cast<LayerD3D10*>(mFirstChild->ImplData());
}
void
ContainerLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
{
float renderTargetOffset[] = { 0, 0 };
nsIntRect visibleRect = mVisibleRegion.GetBounds();
float opacity = GetOpacity() * aOpacity;
gfx3DMatrix transform = mTransform * aTransform;
PRBool useIntermediate = ShouldUseIntermediate(aOpacity, transform);
nsRefPtr<ID3D10RenderTargetView> previousRTView;
nsRefPtr<ID3D10Texture2D> renderTexture;
nsRefPtr<ID3D10RenderTargetView> rtView;
float previousRenderTargetOffset[2];
nsIntSize previousViewportSize;
gfx3DMatrix oldViewMatrix;
if (useIntermediate) {
device()->OMGetRenderTargets(1, getter_AddRefs(previousRTView), NULL);
D3D10_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(D3D10_TEXTURE2D_DESC));
desc.ArraySize = 1;
desc.MipLevels = 1;
desc.Width = visibleRect.width;
desc.Height = visibleRect.height;
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
desc.SampleDesc.Count = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
device()->CreateTexture2D(&desc, NULL, getter_AddRefs(renderTexture));
device()->CreateRenderTargetView(renderTexture, NULL, getter_AddRefs(rtView));
float black[] = { 0, 0, 0, 0};
device()->ClearRenderTargetView(rtView, black);
ID3D10RenderTargetView *rtViewPtr = rtView;
device()->OMSetRenderTargets(1, &rtViewPtr, NULL);
effect()->GetVariableByName("vRenderTargetOffset")->
GetRawValue(previousRenderTargetOffset, 0, 8);
renderTargetOffset[0] = (float)visibleRect.x;
renderTargetOffset[1] = (float)visibleRect.y;
effect()->GetVariableByName("vRenderTargetOffset")->
SetRawValue(renderTargetOffset, 0, 8);
previousViewportSize = mD3DManager->GetViewport();
mD3DManager->SetViewport(nsIntSize(visibleRect.Size()));
}
/*
* Render this container's contents.
*/
LayerD3D10 *layerToRender = GetFirstChildD3D10();
while (layerToRender) {
const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect();
D3D10_RECT oldScissor;
if (clipRect || useIntermediate) {
UINT numRects = 1;
device()->RSGetScissorRects(&numRects, &oldScissor);
RECT r;
if (clipRect) {
r.left = (LONG)(clipRect->x - renderTargetOffset[0]);
r.top = (LONG)(clipRect->y - renderTargetOffset[1]);
r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width);
r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height);
} else {
// useIntermediate == true
r.left = 0;
r.top = 0;
r.right = visibleRect.width;
r.bottom = visibleRect.height;
}
D3D10_RECT d3drect;
if (!useIntermediate) {
// Scissor rect should be an intersection of the old and current scissor.
r.left = NS_MAX<PRInt32>(oldScissor.left, r.left);
r.right = NS_MIN<PRInt32>(oldScissor.right, r.right);
r.top = NS_MAX<PRInt32>(oldScissor.top, r.top);
r.bottom = NS_MIN<PRInt32>(oldScissor.bottom, r.bottom);
}
if (r.left >= r.right || r.top >= r.bottom) {
// Entire layer's clipped out, don't bother drawing.
Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
layerToRender = nextSibling ? static_cast<LayerD3D10*>(nextSibling->
ImplData())
: nsnull;
continue;
}
d3drect.left = NS_MAX<PRInt32>(r.left, 0);
d3drect.top = NS_MAX<PRInt32>(r.top, 0);
d3drect.bottom = r.bottom;
d3drect.right = r.right;
device()->RSSetScissorRects(1, &d3drect);
}
// SetScissorRect
if (!useIntermediate) {
layerToRender->RenderLayer(opacity, transform);
} else {
layerToRender->RenderLayer(1.0f, gfx3DMatrix());
}
if (clipRect || useIntermediate) {
device()->RSSetScissorRects(1, &oldScissor);
}
Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
layerToRender = nextSibling ? static_cast<LayerD3D10*>(nextSibling->
ImplData())
: nsnull;
}
if (useIntermediate) {
mD3DManager->SetViewport(previousViewportSize);
ID3D10RenderTargetView *rtView = previousRTView;
device()->OMSetRenderTargets(1, &rtView, NULL);
effect()->GetVariableByName("vRenderTargetOffset")->
SetRawValue(previousRenderTargetOffset, 0, 8);
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(opacity);
ID3D10EffectTechnique *technique;
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)visibleRect.x,
(float)visibleRect.y,
(float)visibleRect.width,
(float)visibleRect.height)
);
technique->GetPassByIndex(0)->Apply(0);
ID3D10ShaderResourceView *view;
device()->CreateShaderResourceView(renderTexture, NULL, &view);
device()->PSSetShaderResources(0, 1, &view);
device()->Draw(4, 0);
view->Release();
}
}
void
ContainerLayerD3D10::LayerManagerDestroyed()
{
while (mFirstChild) {
GetFirstChildD3D10()->LayerManagerDestroyed();
RemoveChild(mFirstChild);
}
}
void
ContainerLayerD3D10::Validate()
{
Layer *layer = GetFirstChild();
while (layer) {
static_cast<LayerD3D10*>(layer->ImplData())->Validate();
layer = layer->GetNextSibling();
}
}
bool
ContainerLayerD3D10::ShouldUseIntermediate(float aOpacity,
const gfx3DMatrix &aMatrix)
{
if (aOpacity == 1.0f && aMatrix.IsIdentity()) {
return false;
}
Layer *firstChild = GetFirstChild();
if (!firstChild || (!firstChild->GetNextSibling() &&
!firstChild->GetClipRect())) {
// If we forward our transform to a child without using an intermediate, we
// need to be sure that child does not have a clip rect since the clip rect
// needs to be applied after its transform.
return false;
}
if (aMatrix.IsIdentity() && (!firstChild || !firstChild->GetNextSibling())) {
// If there's no transforms applied and a single child, opacity can always
// be forwarded to our only child.
return false;
}
return true;
}
} /* layers */
} /* mozilla */

View File

@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_CONTAINERLAYERD3D10_H
#define GFX_CONTAINERLAYERD3D10_H
#include "Layers.h"
#include "LayerManagerD3D10.h"
namespace mozilla {
namespace layers {
class ContainerLayerD3D10 : public ContainerLayer,
public LayerD3D10
{
public:
ContainerLayerD3D10(LayerManagerD3D10 *aManager);
~ContainerLayerD3D10();
nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); }
/* ContainerLayer implementation */
virtual void InsertAfter(Layer* aChild, Layer* aAfter);
virtual void RemoveChild(Layer* aChild);
/* LayerD3D10 implementation */
Layer* GetLayer();
LayerD3D10* GetFirstChildD3D10();
void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
void Validate();
virtual void LayerManagerDestroyed();
private:
bool ShouldUseIntermediate(float aOpacity, const gfx3DMatrix &aTransform);
};
} /* layers */
} /* mozilla */
#endif /* GFX_CONTAINERLAYERD3D10_H */

View File

@ -0,0 +1,395 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ImageLayerD3D10.h"
#include "gfxImageSurface.h"
#include "yuv_convert.h"
namespace mozilla {
namespace layers {
using mozilla::MutexAutoLock;
ImageContainerD3D10::ImageContainerD3D10(LayerManagerD3D10 *aManager)
: ImageContainer(aManager)
, mActiveImageLock("mozilla.layers.ImageContainerD3D10.mActiveImageLock")
{
}
already_AddRefed<Image>
ImageContainerD3D10::CreateImage(const Image::Format *aFormats,
PRUint32 aNumFormats)
{
if (!aNumFormats) {
return nsnull;
}
nsRefPtr<Image> img;
if (aFormats[0] == Image::PLANAR_YCBCR) {
img = new PlanarYCbCrImageD3D10(static_cast<LayerManagerD3D10*>(mManager));
} else if (aFormats[0] == Image::CAIRO_SURFACE) {
img = new CairoImageD3D10(static_cast<LayerManagerD3D10*>(mManager));
}
return img.forget();
}
void
ImageContainerD3D10::SetCurrentImage(Image *aImage)
{
MutexAutoLock lock(mActiveImageLock);
mActiveImage = aImage;
}
already_AddRefed<Image>
ImageContainerD3D10::GetCurrentImage()
{
MutexAutoLock lock(mActiveImageLock);
nsRefPtr<Image> retval = mActiveImage;
return retval.forget();
}
already_AddRefed<gfxASurface>
ImageContainerD3D10::GetCurrentAsSurface(gfxIntSize *aSize)
{
MutexAutoLock lock(mActiveImageLock);
if (!mActiveImage) {
return nsnull;
}
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
PlanarYCbCrImageD3D10 *yuvImage =
static_cast<PlanarYCbCrImageD3D10*>(mActiveImage.get());
if (yuvImage->HasData()) {
*aSize = yuvImage->mSize;
}
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
CairoImageD3D10 *cairoImage =
static_cast<CairoImageD3D10*>(mActiveImage.get());
*aSize = cairoImage->mSize;
}
return static_cast<ImageD3D10*>(mActiveImage->GetImplData())->GetAsSurface();
}
gfxIntSize
ImageContainerD3D10::GetCurrentSize()
{
MutexAutoLock lock(mActiveImageLock);
if (!mActiveImage) {
return gfxIntSize(0,0);
}
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
PlanarYCbCrImageD3D10 *yuvImage =
static_cast<PlanarYCbCrImageD3D10*>(mActiveImage.get());
if (!yuvImage->HasData()) {
return gfxIntSize(0,0);
}
return yuvImage->mSize;
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
CairoImageD3D10 *cairoImage =
static_cast<CairoImageD3D10*>(mActiveImage.get());
return cairoImage->mSize;
}
return gfxIntSize(0,0);
}
PRBool
ImageContainerD3D10::SetLayerManager(LayerManager *aManager)
{
// we can't do anything here for now
return PR_FALSE;
}
Layer*
ImageLayerD3D10::GetLayer()
{
return this;
}
void
ImageLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
{
if (!GetContainer()) {
return;
}
nsRefPtr<Image> image = GetContainer()->GetCurrentImage();
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity);
ID3D10EffectTechnique *technique;
if (image->GetFormat() == Image::PLANAR_YCBCR) {
PlanarYCbCrImageD3D10 *yuvImage =
static_cast<PlanarYCbCrImageD3D10*>(image.get());
if (!yuvImage->HasData()) {
return;
}
// TODO: At some point we should try to deal with mFilter here, you don't
// really want to use point filtering in the case of NEAREST, since that
// would also use point filtering for Chroma upsampling. Where most likely
// the user would only want point filtering for final RGB image upsampling.
technique = effect()->GetTechniqueByName("RenderYCbCrLayer");
effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(yuvImage->mYView);
effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(yuvImage->mCbView);
effect()->GetVariableByName("tCr")->AsShaderResource()->SetResource(yuvImage->mCrView);
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)0,
(float)0,
(float)yuvImage->mSize.width,
(float)yuvImage->mSize.height)
);
} else if (image->GetFormat() == Image::CAIRO_SURFACE) {
CairoImageD3D10 *cairoImage =
static_cast<CairoImageD3D10*>(image.get());
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
}
if (cairoImage->mSRView) {
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(cairoImage->mSRView);
}
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)0,
(float)0,
(float)cairoImage->mSize.width,
(float)cairoImage->mSize.height)
);
}
technique->GetPassByIndex(0)->Apply(0);
device()->Draw(4, 0);
}
PlanarYCbCrImageD3D10::PlanarYCbCrImageD3D10(mozilla::layers::LayerManagerD3D10* aManager)
: PlanarYCbCrImage(static_cast<ImageD3D10*>(this))
, mManager(aManager)
, mHasData(PR_FALSE)
{
}
void
PlanarYCbCrImageD3D10::SetData(const PlanarYCbCrImage::Data &aData)
{
// XXX - For D3D10Ex we really should just copy to systemmem surfaces here.
// For now, we copy the data
int width_shift = 0;
int height_shift = 0;
if (aData.mYSize.width == aData.mCbCrSize.width &&
aData.mYSize.height == aData.mCbCrSize.height) {
// YV24 format
width_shift = 0;
height_shift = 0;
mType = gfx::YV24;
} else if (aData.mYSize.width / 2 == aData.mCbCrSize.width &&
aData.mYSize.height == aData.mCbCrSize.height) {
// YV16 format
width_shift = 1;
height_shift = 0;
mType = gfx::YV16;
} else if (aData.mYSize.width / 2 == aData.mCbCrSize.width &&
aData.mYSize.height / 2 == aData.mCbCrSize.height ) {
// YV12 format
width_shift = 1;
height_shift = 1;
mType = gfx::YV12;
} else {
NS_ERROR("YCbCr format not supported");
}
mData = aData;
mData.mCbCrStride = mData.mCbCrSize.width = aData.mPicSize.width >> width_shift;
// Round up the values for width and height to make sure we sample enough data
// for the last pixel - See bug 590735
if (width_shift && (aData.mPicSize.width & 1)) {
mData.mCbCrStride++;
mData.mCbCrSize.width++;
}
mData.mCbCrSize.height = aData.mPicSize.height >> height_shift;
if (height_shift && (aData.mPicSize.height & 1)) {
mData.mCbCrSize.height++;
}
mData.mYSize = aData.mPicSize;
mData.mYStride = mData.mYSize.width;
mBuffer = new PRUint8[mData.mCbCrStride * mData.mCbCrSize.height * 2 +
mData.mYStride * mData.mYSize.height];
mData.mYChannel = mBuffer;
mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
int cbcr_x = aData.mPicX >> width_shift;
int cbcr_y = aData.mPicY >> height_shift;
for (int i = 0; i < mData.mYSize.height; i++) {
memcpy(mData.mYChannel + i * mData.mYStride,
aData.mYChannel + ((aData.mPicY + i) * aData.mYStride) + aData.mPicX,
mData.mYStride);
}
for (int i = 0; i < mData.mCbCrSize.height; i++) {
memcpy(mData.mCbChannel + i * mData.mCbCrStride,
aData.mCbChannel + ((cbcr_y + i) * aData.mCbCrStride) + cbcr_x,
mData.mCbCrStride);
}
for (int i = 0; i < mData.mCbCrSize.height; i++) {
memcpy(mData.mCrChannel + i * mData.mCbCrStride,
aData.mCrChannel + ((cbcr_y + i) * aData.mCbCrStride) + cbcr_x,
mData.mCbCrStride);
}
// Fix picture rect to be correct
mData.mPicX = mData.mPicY = 0;
mSize = aData.mPicSize;
AllocateTextures();
mHasData = PR_TRUE;
}
void
PlanarYCbCrImageD3D10::AllocateTextures()
{
D3D10_SUBRESOURCE_DATA dataY;
D3D10_SUBRESOURCE_DATA dataCb;
D3D10_SUBRESOURCE_DATA dataCr;
CD3D10_TEXTURE2D_DESC descY(DXGI_FORMAT_R8_UNORM,
mData.mYSize.width,
mData.mYSize.height, 1, 1);
CD3D10_TEXTURE2D_DESC descCbCr(DXGI_FORMAT_R8_UNORM,
mData.mCbCrSize.width,
mData.mCbCrSize.height, 1, 1);
descY.Usage = descCbCr.Usage = D3D10_USAGE_IMMUTABLE;
dataY.pSysMem = mData.mYChannel;
dataY.SysMemPitch = mData.mYStride;
dataCb.pSysMem = mData.mCbChannel;
dataCb.SysMemPitch = mData.mCbCrStride;
dataCr.pSysMem = mData.mCrChannel;
dataCr.SysMemPitch = mData.mCbCrStride;
mManager->device()->CreateTexture2D(&descY, &dataY, getter_AddRefs(mYTexture));
mManager->device()->CreateTexture2D(&descCbCr, &dataCb, getter_AddRefs(mCbTexture));
mManager->device()->CreateTexture2D(&descCbCr, &dataCr, getter_AddRefs(mCrTexture));
mManager->device()->CreateShaderResourceView(mYTexture, NULL, getter_AddRefs(mYView));
mManager->device()->CreateShaderResourceView(mCbTexture, NULL, getter_AddRefs(mCbView));
mManager->device()->CreateShaderResourceView(mCrTexture, NULL, getter_AddRefs(mCrView));
}
already_AddRefed<gfxASurface>
PlanarYCbCrImageD3D10::GetAsSurface()
{
nsRefPtr<gfxImageSurface> imageSurface =
new gfxImageSurface(mSize, gfxASurface::ImageFormatRGB24);
// Convert from YCbCr to RGB now
gfx::ConvertYCbCrToRGB32(mData.mYChannel,
mData.mCbChannel,
mData.mCrChannel,
imageSurface->Data(),
0,
0,
mSize.width,
mSize.height,
mData.mYStride,
mData.mCbCrStride,
imageSurface->Stride(),
mType);
return imageSurface.forget().get();
}
CairoImageD3D10::~CairoImageD3D10()
{
}
void
CairoImageD3D10::SetData(const CairoImage::Data &aData)
{
mSize = aData.mSize;
nsRefPtr<gfxImageSurface> imageSurface;
if (aData.mSurface->GetType() == gfxASurface::SurfaceTypeImage) {
imageSurface = static_cast<gfxImageSurface*>(aData.mSurface);
} else {
imageSurface = new gfxImageSurface(aData.mSize,
gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
context->SetSource(aData.mSurface);
context->SetOperator(gfxContext::OPERATOR_SOURCE);
context->Paint();
}
D3D10_SUBRESOURCE_DATA data;
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mSize.width, mSize.height, 1, 1);
desc.Usage = D3D10_USAGE_IMMUTABLE;
data.pSysMem = imageSurface->Data();
data.SysMemPitch = imageSurface->Stride();
mManager->device()->CreateTexture2D(&desc, &data, getter_AddRefs(mTexture));
mManager->device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
}
already_AddRefed<gfxASurface>
CairoImageD3D10::GetAsSurface()
{
return nsnull;
}
} /* layers */
} /* mozilla */

View File

@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_IMAGELAYERD3D10_H
#define GFX_IMAGELAYERD3D10_H
#include "LayerManagerD3D10.h"
#include "ImageLayers.h"
#include "yuv_convert.h"
#include "mozilla/Mutex.h"
namespace mozilla {
namespace layers {
class THEBES_API ImageContainerD3D10 : public ImageContainer
{
public:
ImageContainerD3D10(LayerManagerD3D10 *aManager);
virtual ~ImageContainerD3D10() {}
virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
PRUint32 aNumFormats);
virtual void SetCurrentImage(Image* aImage);
virtual already_AddRefed<Image> GetCurrentImage();
virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize);
virtual gfxIntSize GetCurrentSize();
virtual PRBool SetLayerManager(LayerManager *aManager);
private:
typedef mozilla::Mutex Mutex;
nsRefPtr<Image> mActiveImage;
Mutex mActiveImageLock;
};
class THEBES_API ImageLayerD3D10 : public ImageLayer,
public LayerD3D10
{
public:
ImageLayerD3D10(LayerManagerD3D10 *aManager)
: ImageLayer(aManager, NULL)
, LayerD3D10(aManager)
{
mImplData = static_cast<LayerD3D10*>(this);
}
// LayerD3D10 Implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
};
class THEBES_API ImageD3D10
{
public:
virtual already_AddRefed<gfxASurface> GetAsSurface() = 0;
};
class THEBES_API PlanarYCbCrImageD3D10 : public PlanarYCbCrImage,
public ImageD3D10
{
public:
PlanarYCbCrImageD3D10(LayerManagerD3D10 *aManager);
~PlanarYCbCrImageD3D10() {}
virtual void SetData(const Data &aData);
/*
* Upload the data from out mData into our textures. For now we use this to
* make sure the textures are created and filled on the main thread.
*/
void AllocateTextures();
PRBool HasData() { return mHasData; }
virtual already_AddRefed<gfxASurface> GetAsSurface();
nsAutoArrayPtr<PRUint8> mBuffer;
LayerManagerD3D10 *mManager;
Data mData;
gfxIntSize mSize;
nsRefPtr<ID3D10Texture2D> mYTexture;
nsRefPtr<ID3D10Texture2D> mCrTexture;
nsRefPtr<ID3D10Texture2D> mCbTexture;
nsRefPtr<ID3D10ShaderResourceView> mYView;
nsRefPtr<ID3D10ShaderResourceView> mCbView;
nsRefPtr<ID3D10ShaderResourceView> mCrView;
PRPackedBool mHasData;
gfx::YUVType mType;
};
class THEBES_API CairoImageD3D10 : public CairoImage,
public ImageD3D10
{
public:
CairoImageD3D10(LayerManagerD3D10 *aManager)
: CairoImage(static_cast<ImageD3D10*>(this))
, mManager(aManager)
{ }
~CairoImageD3D10();
virtual void SetData(const Data &aData);
virtual already_AddRefed<gfxASurface> GetAsSurface();
nsRefPtr<ID3D10Texture2D> mTexture;
nsRefPtr<ID3D10ShaderResourceView> mSRView;
gfxIntSize mSize;
LayerManagerD3D10 *mManager;
};
} /* layers */
} /* mozilla */
#endif /* GFX_IMAGELAYERD3D10_H */

View File

@ -0,0 +1,502 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "LayerManagerD3D10.h"
#include "LayerManagerD3D10Effect.h"
#include "gfxWindowsPlatform.h"
#include "gfxD2DSurface.h"
#include "cairo-win32.h"
#include "dxgi.h"
#include "ContainerLayerD3D10.h"
#include "ThebesLayerD3D10.h"
#include "ColorLayerD3D10.h"
#include "CanvasLayerD3D10.h"
#include "ImageLayerD3D10.h"
namespace mozilla {
namespace layers {
typedef HRESULT (WINAPI*D3D10CreateEffectFromMemoryFunc)(
void *pData,
SIZE_T DataLength,
UINT FXFlags,
ID3D10Device *pDevice,
ID3D10EffectPool *pEffectPool,
ID3D10Effect **ppEffect
);
struct Vertex
{
float position[2];
};
// {17F88CCB-1F49-4c08-8002-ADA7BD44856D}
static const GUID sEffect =
{ 0x17f88ccb, 0x1f49, 0x4c08, { 0x80, 0x2, 0xad, 0xa7, 0xbd, 0x44, 0x85, 0x6d } };
// {19599D91-912C-4C2F-A8C5-299DE85FBD34}
static const GUID sInputLayout =
{ 0x19599d91, 0x912c, 0x4c2f, { 0xa8, 0xc5, 0x29, 0x9d, 0xe8, 0x5f, 0xbd, 0x34 } };
// {293157D2-09C7-4680-AE27-C28E370E418B}
static const GUID sVertexBuffer =
{ 0x293157d2, 0x9c7, 0x4680, { 0xae, 0x27, 0xc2, 0x8e, 0x37, 0xe, 0x41, 0x8b } };
cairo_user_data_key_t gKeyD3D10Texture;
LayerManagerD3D10::LayerManagerD3D10(nsIWidget *aWidget)
: mWidget(aWidget)
{
}
LayerManagerD3D10::~LayerManagerD3D10()
{
}
bool
LayerManagerD3D10::Initialize()
{
HRESULT hr;
cairo_device_t *device = gfxWindowsPlatform::GetPlatform()->GetD2DDevice();
if (!device) {
return false;
}
mDevice = cairo_d2d_device_get_device(device);
UINT size = 4;
if (FAILED(mDevice->GetPrivateData(sEffect, &size, mEffect.StartAssignment()))) {
D3D10CreateEffectFromMemoryFunc createEffect = (D3D10CreateEffectFromMemoryFunc)
GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateEffectFromMemory");
if (!createEffect) {
return false;
}
hr = createEffect((void*)g_main,
sizeof(g_main),
D3D10_EFFECT_SINGLE_THREADED,
mDevice,
NULL,
getter_AddRefs(mEffect));
if (FAILED(hr)) {
return false;
}
mDevice->SetPrivateDataInterface(sEffect, mEffect);
}
size = 4;
if (FAILED(mDevice->GetPrivateData(sInputLayout, &size, mInputLayout.StartAssignment()))) {
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
D3D10_PASS_DESC passDesc;
mEffect->GetTechniqueByName("RenderRGBLayerPremul")->GetPassByIndex(0)->
GetDesc(&passDesc);
hr = mDevice->CreateInputLayout(layout,
sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC),
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
getter_AddRefs(mInputLayout));
if (FAILED(hr)) {
return false;
}
mDevice->SetPrivateDataInterface(sInputLayout, mInputLayout);
}
size = 4;
if (FAILED(mDevice->GetPrivateData(sVertexBuffer, &size, mVertexBuffer.StartAssignment()))) {
Vertex vertices[] = { {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} };
CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
D3D10_SUBRESOURCE_DATA data;
data.pSysMem = (void*)vertices;
hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer));
if (FAILED(hr)) {
return false;
}
mDevice->SetPrivateDataInterface(sVertexBuffer, mVertexBuffer);
}
nsRefPtr<IDXGIDevice> dxgiDevice;
nsRefPtr<IDXGIAdapter> dxgiAdapter;
nsRefPtr<IDXGIFactory> dxgiFactory;
mDevice->QueryInterface(dxgiDevice.StartAssignment());
dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter));
dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
DXGI_SWAP_CHAIN_DESC swapDesc;
::ZeroMemory(&swapDesc, sizeof(swapDesc));
swapDesc.BufferDesc.Width = 0;
swapDesc.BufferDesc.Height = 0;
swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapDesc.BufferDesc.RefreshRate.Numerator = 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.SampleDesc.Count = 1;
swapDesc.SampleDesc.Quality = 0;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.BufferCount = 1;
swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
swapDesc.Windowed = TRUE;
/**
* Create a swap chain, this swap chain will contain the backbuffer for
* the window we draw to. The front buffer is the full screen front
* buffer.
*/
hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, getter_AddRefs(mSwapChain));
if (FAILED(hr)) {
return false;
}
return true;
}
void
LayerManagerD3D10::SetRoot(Layer *aRoot)
{
mRoot = aRoot;
}
void
LayerManagerD3D10::BeginTransaction()
{
}
void
LayerManagerD3D10::BeginTransactionWithTarget(gfxContext* aTarget)
{
mTarget = aTarget;
}
void
LayerManagerD3D10::EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData)
{
mCurrentCallbackInfo.Callback = aCallback;
mCurrentCallbackInfo.CallbackData = aCallbackData;
Render();
mCurrentCallbackInfo.Callback = nsnull;
mCurrentCallbackInfo.CallbackData = nsnull;
mTarget = nsnull;
}
already_AddRefed<ThebesLayer>
LayerManagerD3D10::CreateThebesLayer()
{
nsRefPtr<ThebesLayer> layer = new ThebesLayerD3D10(this);
return layer.forget();
}
already_AddRefed<ContainerLayer>
LayerManagerD3D10::CreateContainerLayer()
{
nsRefPtr<ContainerLayer> layer = new ContainerLayerD3D10(this);
return layer.forget();
}
already_AddRefed<ImageLayer>
LayerManagerD3D10::CreateImageLayer()
{
nsRefPtr<ImageLayer> layer = new ImageLayerD3D10(this);
return layer.forget();
}
already_AddRefed<ColorLayer>
LayerManagerD3D10::CreateColorLayer()
{
nsRefPtr<ColorLayer> layer = new ColorLayerD3D10(this);
return layer.forget();
}
already_AddRefed<CanvasLayer>
LayerManagerD3D10::CreateCanvasLayer()
{
nsRefPtr<CanvasLayer> layer = new CanvasLayerD3D10(this);
return layer.forget();
}
already_AddRefed<ImageContainer>
LayerManagerD3D10::CreateImageContainer()
{
nsRefPtr<ImageContainer> layer = new ImageContainerD3D10(this);
return layer.forget();
}
static void ReleaseTexture(void *texture)
{
static_cast<ID3D10Texture2D*>(texture)->Release();
}
already_AddRefed<gfxASurface>
LayerManagerD3D10::CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat aFormat)
{
if ((aFormat != gfxASurface::ImageFormatRGB24 &&
aFormat != gfxASurface::ImageFormatARGB32)) {
return LayerManager::CreateOptimalSurface(aSize, aFormat);
}
nsRefPtr<ID3D10Texture2D> texture;
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(texture));
if (FAILED(hr)) {
NS_WARNING("Failed to create new texture for CreateOptimalSurface!");
return LayerManager::CreateOptimalSurface(aSize, aFormat);
}
nsRefPtr<gfxD2DSurface> surface =
new gfxD2DSurface(texture, aFormat == gfxASurface::ImageFormatRGB24 ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
if (!surface || surface->CairoStatus()) {
return LayerManager::CreateOptimalSurface(aSize, aFormat);
}
surface->SetData(&gKeyD3D10Texture,
texture.forget().get(),
ReleaseTexture);
return surface.forget();
}
void
LayerManagerD3D10::SetViewport(const nsIntSize &aViewport)
{
mViewport = aViewport;
D3D10_VIEWPORT viewport;
viewport.MaxDepth = 1.0f;
viewport.MinDepth = 0;
viewport.Width = aViewport.width;
viewport.Height = aViewport.height;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
mDevice->RSSetViewports(1, &viewport);
gfx3DMatrix projection;
/*
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
* <1.0, -1.0> bottomright)
*/
projection._11 = 2.0f / aViewport.width;
projection._22 = -2.0f / aViewport.height;
projection._33 = 1.0f;
projection._41 = -1.0f;
projection._42 = 1.0f;
projection._44 = 1.0f;
HRESULT hr = mEffect->GetVariableByName("mProjection")->
SetRawValue(&projection._11, 0, 64);
if (FAILED(hr)) {
NS_WARNING("Failed to set projection matrix.");
}
}
void
LayerManagerD3D10::SetupPipeline()
{
VerifyBufferSize();
UpdateRenderTarget();
nsIntRect rect;
mWidget->GetClientBounds(rect);
HRESULT hr;
hr = mEffect->GetVariableByName("vTextureCoords")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
if (FAILED(hr)) {
NS_WARNING("Failed to set Texture Coordinates.");
return;
}
ID3D10RenderTargetView *view = mRTView;
mDevice->OMSetRenderTargets(1, &view, NULL);
mDevice->IASetInputLayout(mInputLayout);
UINT stride = sizeof(Vertex);
UINT offset = 0;
ID3D10Buffer *buffer = mVertexBuffer;
mDevice->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
SetViewport(nsIntSize(rect.width, rect.height));
}
void
LayerManagerD3D10::UpdateRenderTarget()
{
if (mRTView) {
return;
}
HRESULT hr;
nsRefPtr<ID3D10Texture2D> backBuf;
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
if (FAILED(hr)) {
return;
}
mDevice->CreateRenderTargetView(backBuf, NULL, getter_AddRefs(mRTView));
}
void
LayerManagerD3D10::VerifyBufferSize()
{
DXGI_SWAP_CHAIN_DESC swapDesc;
mSwapChain->GetDesc(&swapDesc);
nsIntRect rect;
mWidget->GetClientBounds(rect);
if (swapDesc.BufferDesc.Width == rect.width &&
swapDesc.BufferDesc.Height == rect.height) {
return;
}
mRTView = nsnull;
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
DXGI_FORMAT_B8G8R8A8_UNORM, 0);
}
void
LayerManagerD3D10::Render()
{
if (mRoot) {
static_cast<LayerD3D10*>(mRoot->ImplData())->Validate();
}
SetupPipeline();
float black[] = { 0, 0, 0, 0 };
device()->ClearRenderTargetView(mRTView, black);
nsIntRect rect;
mWidget->GetClientBounds(rect);
if (mRoot) {
const nsIntRect *clipRect = mRoot->GetClipRect();
D3D10_RECT r;
if (clipRect) {
r.left = (LONG)clipRect->x;
r.top = (LONG)clipRect->y;
r.right = (LONG)(clipRect->x + clipRect->width);
r.bottom = (LONG)(clipRect->y + clipRect->height);
} else {
r.left = r.top = 0;
r.right = rect.width;
r.bottom = rect.height;
}
device()->RSSetScissorRects(1, &r);
static_cast<LayerD3D10*>(mRoot->ImplData())->RenderLayer(1, gfx3DMatrix());
}
if (mTarget) {
PaintToTarget();
} else {
mSwapChain->Present(0, 0);
}
}
void
LayerManagerD3D10::PaintToTarget()
{
nsRefPtr<ID3D10Texture2D> backBuf;
mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
D3D10_TEXTURE2D_DESC bbDesc;
backBuf->GetDesc(&bbDesc);
CD3D10_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height);
softDesc.MipLevels = 1;
softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
softDesc.Usage = D3D10_USAGE_STAGING;
softDesc.BindFlags = 0;
nsRefPtr<ID3D10Texture2D> readTexture;
device()->CreateTexture2D(&softDesc, NULL, getter_AddRefs(readTexture));
device()->CopyResource(readTexture, backBuf);
D3D10_MAPPED_TEXTURE2D map;
readTexture->Map(0, D3D10_MAP_READ, 0, &map);
nsRefPtr<gfxImageSurface> tmpSurface =
new gfxImageSurface((unsigned char*)map.pData,
gfxIntSize(bbDesc.Width, bbDesc.Height),
map.RowPitch,
gfxASurface::ImageFormatARGB32);
mTarget->SetSource(tmpSurface);
mTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
mTarget->Paint();
}
LayerD3D10::LayerD3D10(LayerManagerD3D10 *aManager)
: mD3DManager(aManager)
{
}
}
}

View File

@ -0,0 +1,248 @@
typedef float4 rect;
cbuffer PerLayer {
rect vTextureCoords;
rect vLayerQuad;
float fLayerOpacity;
float4x4 mLayerTransform;
}
cbuffer PerOccasionalLayer {
float4 vRenderTargetOffset;
float4 fLayerColor;
}
cbuffer PerLayerManager {
float4x4 mProjection;
}
BlendState Premul
{
AlphaToCoverageEnable = FALSE;
BlendEnable[0] = TRUE;
SrcBlend = One;
DestBlend = Inv_Src_Alpha;
BlendOp = Add;
SrcBlendAlpha = One;
DestBlendAlpha = Inv_Src_Alpha;
BlendOpAlpha = Add;
RenderTargetWriteMask[0] = 0x0F; // All
};
BlendState NonPremul
{
AlphaToCoverageEnable = FALSE;
BlendEnable[0] = TRUE;
SrcBlend = Src_Alpha;
DestBlend = Inv_Src_Alpha;
BlendOp = Add;
SrcBlendAlpha = One;
DestBlendAlpha = Inv_Src_Alpha;
BlendOpAlpha = Add;
RenderTargetWriteMask[0] = 0x0F; // All
};
RasterizerState LayerRast
{
ScissorEnable = True;
};
Texture2D tRGB;
Texture2D tY;
Texture2D tCb;
Texture2D tCr;
SamplerState LayerTextureSamplerLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
SamplerState LayerTextureSamplerPoint
{
Filter = MIN_MAG_MIP_POINT;
AddressU = Wrap;
AddressV = Wrap;
};
struct VS_INPUT {
float2 vPosition : POSITION;
};
struct VS_OUTPUT {
float4 vPosition : SV_Position;
float2 vTexCoords : TEXCOORD0;
};
VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
{
VS_OUTPUT outp;
outp.vPosition.z = 0;
outp.vPosition.w = 1;
// We use 4 component floats to uniquely describe a rectangle, by the structure
// of x, y, width, height. This allows us to easily generate the 4 corners
// of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the
// stream source for our LayerQuad vertex shader. We do this by doing:
// Xout = x + Xin * width
// Yout = y + Yin * height
float2 position = vLayerQuad.xy;
float2 size = vLayerQuad.zw;
outp.vPosition.x = position.x + aVertex.vPosition.x * size.x;
outp.vPosition.y = position.y + aVertex.vPosition.y * size.y;
outp.vPosition = mul(mLayerTransform, outp.vPosition);
outp.vPosition = outp.vPosition - vRenderTargetOffset;
outp.vPosition = mul(mProjection, outp.vPosition);
position = vTextureCoords.xy;
size = vTextureCoords.zw;
outp.vTexCoords.x = position.x + aVertex.vPosition.x * size.x;
outp.vTexCoords.y = position.y + aVertex.vPosition.y * size.y;
return outp;
}
float4 RGBAShaderLinear(const VS_OUTPUT aVertex) : SV_Target
{
return tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) * fLayerOpacity;
}
float4 RGBAShaderPoint(const VS_OUTPUT aVertex) : SV_Target
{
return tRGB.Sample(LayerTextureSamplerPoint, aVertex.vTexCoords) * fLayerOpacity;
}
float4 RGBShaderLinear(const VS_OUTPUT aVertex) : SV_Target
{
float4 result;
result = tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) * fLayerOpacity;
result.a = fLayerOpacity;
return result;
}
float4 RGBShaderPoint(const VS_OUTPUT aVertex) : SV_Target
{
float4 result;
result = tRGB.Sample(LayerTextureSamplerPoint, aVertex.vTexCoords) * fLayerOpacity;
result.a = fLayerOpacity;
return result;
}
float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target
{
float4 yuv;
float4 color;
yuv.r = tCr.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords).r - 0.5;
yuv.g = tY.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords).r - 0.0625;
yuv.b = tCb.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords).r - 0.5;
color.r = yuv.g * 1.164 + yuv.r * 1.596;
color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b;
color.b = yuv.g * 1.164 + yuv.b * 2.018;
color.a = 1.0f;
return color * fLayerOpacity;
}
float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target
{
return fLayerColor;
}
technique10 RenderRGBLayerPremul
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShaderLinear() ) );
}
}
technique10 RenderRGBLayerPremulPoint
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShaderPoint() ) );
}
}
technique10 RenderRGBALayerPremul
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderLinear() ) );
}
}
technique10 RenderRGBALayerNonPremul
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderLinear() ) );
}
}
technique10 RenderRGBALayerPremulPoint
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderPoint() ) );
}
}
technique10 RenderRGBALayerNonPremulPoint
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderPoint() ) );
}
}
technique10 RenderYCbCrLayer
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, YCbCrShader() ) );
}
}
technique10 RenderSolidColorLayer
{
pass P0
{
SetRasterizerState( LayerRast );
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0_level_9_3, SolidColorShader() ) );
}
}

View File

@ -0,0 +1,211 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_LAYERMANAGERD3D10_H
#define GFX_LAYERMANAGERD3D10_H
#include "Layers.h"
#include <windows.h>
#include <d3d10_1.h>
#include "gfxContext.h"
#include "nsIWidget.h"
namespace mozilla {
namespace layers {
/**
* This structure is used to pass rectangles to our shader constant. We can use
* this for passing rectangular areas to SetVertexShaderConstant. In the format
* of a 4 component float(x,y,width,height). Our vertex shader can then use
* this to construct rectangular positions from the 0,0-1,1 quad that we source
* it with.
*/
struct ShaderConstantRectD3D10
{
float mX, mY, mWidth, mHeight;
ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight)
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
{ }
// For easy passing to SetVertexShaderConstantF.
operator float* () { return &mX; }
};
extern cairo_user_data_key_t gKeyD3D10Texture;
/*
* This is the LayerManager used for Direct3D 9. For now this will render on
* the main thread.
*/
class THEBES_API LayerManagerD3D10 : public LayerManager {
public:
LayerManagerD3D10(nsIWidget *aWidget);
virtual ~LayerManagerD3D10();
/*
* Initializes the layer manager, this is when the layer manager will
* actually access the device and attempt to create the swap chain used
* to draw to the window. If this method fails the device cannot be used.
* This function is not threadsafe.
*
* \return True is initialization was succesful, false when it was not.
*/
bool Initialize();
/*
* LayerManager implementation.
*/
virtual void SetRoot(Layer *aLayer);
void BeginTransaction();
void BeginTransactionWithTarget(gfxContext* aTarget);
struct CallbackInfo {
DrawThebesLayerCallback Callback;
void *CallbackData;
};
void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData);
const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; }
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
virtual already_AddRefed<ImageLayer> CreateImageLayer();
virtual already_AddRefed<ColorLayer> CreateColorLayer();
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
virtual already_AddRefed<ImageContainer> CreateImageContainer();
virtual already_AddRefed<gfxASurface>
CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat imageFormat);
virtual LayersBackend GetBackendType() { return LAYERS_D3D10; }
virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); }
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() const { return "D3D9"; }
#endif // MOZ_LAYERS_HAVE_LOG
// Public helpers
ID3D10Device1 *device() const { return mDevice; }
ID3D10Effect *effect() const { return mEffect; }
void SetViewport(const nsIntSize &aViewport);
const nsIntSize &GetViewport() { return mViewport; }
private:
void SetupPipeline();
void UpdateRenderTarget();
void VerifyBufferSize();
void Render();
nsRefPtr<ID3D10Device1> mDevice;
nsRefPtr<ID3D10Effect> mEffect;
nsRefPtr<ID3D10InputLayout> mInputLayout;
nsRefPtr<ID3D10Buffer> mVertexBuffer;
nsRefPtr<ID3D10RenderTargetView> mRTView;
nsRefPtr<IDXGISwapChain> mSwapChain;
nsIWidget *mWidget;
CallbackInfo mCurrentCallbackInfo;
nsIntSize mViewport;
/*
* Context target, NULL when drawing directly to our swap chain.
*/
nsRefPtr<gfxContext> mTarget;
/*
* Copies the content of our backbuffer to the set transaction target.
*/
void PaintToTarget();
};
/*
* General information and tree management for OGL layers.
*/
class LayerD3D10
{
public:
LayerD3D10(LayerManagerD3D10 *aManager);
virtual LayerD3D10 *GetFirstChildD3D10() { return nsnull; }
void SetFirstChild(LayerD3D10 *aParent);
virtual Layer* GetLayer() = 0;
/**
* This will render a child layer to whatever render target is currently
* active. aOpacity and aTransform will pass any 'carried' transformations
* and/or opacity from the parent. This allows the parent to avoid
* rendering to intermediate surfaces when possible.
*/
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) = 0;
virtual void Validate() {}
ID3D10Device1 *device() const { return mD3DManager->device(); }
ID3D10Effect *effect() const { return mD3DManager->effect(); }
/* Called by the layer manager when it's destroyed */
virtual void LayerManagerDestroyed() {}
protected:
LayerManagerD3D10 *mD3DManager;
};
} /* layers */
} /* mozilla */
#endif /* GFX_LAYERMANAGERD3D9_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,339 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ThebesLayerD3D10.h"
#include "gfxPlatform.h"
#include "gfxWindowsPlatform.h"
#ifdef CAIRO_HAS_D2D_SURFACE
#include "gfxD2DSurface.h"
#endif
namespace mozilla {
namespace layers {
ThebesLayerD3D10::ThebesLayerD3D10(LayerManagerD3D10 *aManager)
: ThebesLayer(aManager, NULL)
, LayerD3D10(aManager)
{
mImplData = static_cast<LayerD3D10*>(this);
}
ThebesLayerD3D10::~ThebesLayerD3D10()
{
}
/**
* Retention threshold - amount of pixels intersection required to enable
* layer content retention. This is a guesstimate. Profiling could be done to
* figure out the optimal threshold.
*/
#define RETENTION_THRESHOLD 16384
void
ThebesLayerD3D10::SetVisibleRegion(const nsIntRegion &aRegion)
{
if (aRegion.IsEqual(mVisibleRegion)) {
return;
}
HRESULT hr;
nsIntRegion oldVisibleRegion = mVisibleRegion;
ThebesLayer::SetVisibleRegion(aRegion);
if (!mTexture) {
// If we don't need to retain content initialize lazily. This is good also
// because we might get mIsOpaqueSurface set later than the first call to
// SetVisibleRegion.
return;
}
VerifyContentType();
nsRefPtr<ID3D10Texture2D> oldTexture = mTexture;
nsIntRect oldBounds = oldVisibleRegion.GetBounds();
nsIntRect newBounds = mVisibleRegion.GetBounds();
CreateNewTexture(gfxIntSize(newBounds.width, newBounds.height));
// Old visible region will become the region that is covered by both the
// old and the new visible region.
oldVisibleRegion.And(oldVisibleRegion, mVisibleRegion);
// No point in retaining parts which were not valid.
oldVisibleRegion.And(oldVisibleRegion, mValidRegion);
nsIntRect largeRect = oldVisibleRegion.GetLargestRectangle();
// If we had no hardware texture before or have no retained area larger than
// the retention threshold, we're not retaining and are done here. If our
// texture creation failed this can mean a device reset is pending and we
// should silently ignore the failure. In the future when device failures
// are properly handled we should test for the type of failure and gracefully
// handle different failures. See bug 569081.
if (!oldTexture || !mTexture ||
largeRect.width * largeRect.height < RETENTION_THRESHOLD) {
mValidRegion.SetEmpty();
return;
}
nsIntRegion retainedRegion;
nsIntRegionRectIterator iter(oldVisibleRegion);
const nsIntRect *r;
while ((r = iter.Next())) {
if (r->width * r->height > RETENTION_THRESHOLD) {
// Calculate the retained rectangle's position on the old and the new
// surface.
D3D10_BOX box;
box.left = r->x - oldBounds.x;
box.top = r->y - oldBounds.y;
box.right = box.left + r->width;
box.bottom = box.top + r->height;
box.back = 1.0f;
box.front = 0;
device()->CopySubresourceRegion(mTexture, 0,
r->x - newBounds.x,
r->y - newBounds.y,
0,
oldTexture, 0,
&box);
if (SUCCEEDED(hr)) {
retainedRegion.Or(retainedRegion, *r);
}
}
}
// Areas which were valid and were retained are still valid
mValidRegion.And(mValidRegion, retainedRegion);
}
void
ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
{
mValidRegion.Sub(mValidRegion, aRegion);
}
void
ThebesLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
{
if (!mTexture) {
return;
}
nsIntRect visibleRect = mVisibleRegion.GetBounds();
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity);
ID3D10EffectTechnique *technique;
if (CanUseOpaqueSurface()) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
}
nsIntRegionRectIterator iter(mVisibleRegion);
const nsIntRect *iterRect;
if (mSRView) {
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
}
while ((iterRect = iter.Next())) {
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)iterRect->x,
(float)iterRect->y,
(float)iterRect->width,
(float)iterRect->height)
);
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)(iterRect->x - visibleRect.x) / (float)visibleRect.width,
(float)(iterRect->y - visibleRect.y) / (float)visibleRect.height,
(float)iterRect->width / (float)visibleRect.width,
(float)iterRect->height / (float)visibleRect.height)
);
technique->GetPassByIndex(0)->Apply(0);
device()->Draw(4, 0);
}
// Set back to default.
effect()->GetVariableByName("vTextureCoords")->AsVector()->
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
}
void
ThebesLayerD3D10::Validate()
{
if (mVisibleRegion.IsEmpty()) {
return;
}
VerifyContentType();
nsIntRect visibleRect = mVisibleRegion.GetBounds();
if (!mTexture) {
CreateNewTexture(gfxIntSize(visibleRect.width, visibleRect.height));
mValidRegion.SetEmpty();
}
if (!mValidRegion.IsEqual(mVisibleRegion)) {
/* We use the bounds of the visible region because we draw the bounds of
* this region when we draw this entire texture. We have to make sure that
* the areas that aren't filled with content get their background drawn.
* This is an issue for opaque surfaces, which otherwise won't get their
* background painted.
*/
nsIntRegion region;
region.Sub(mVisibleRegion, mValidRegion);
DrawRegion(region);
mValidRegion = mVisibleRegion;
}
}
void
ThebesLayerD3D10::LayerManagerDestroyed()
{
mD3DManager = nsnull;
}
Layer*
ThebesLayerD3D10::GetLayer()
{
return this;
}
void
ThebesLayerD3D10::VerifyContentType()
{
if (mD2DSurface) {
gfxASurface::gfxContentType type = CanUseOpaqueSurface() ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA;
if (type != mD2DSurface->GetContentType()) {
mD2DSurface = new gfxD2DSurface(mTexture, type);
if (!mD2DSurface || mD2DSurface->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurface = nsnull;
return;
}
mValidRegion.SetEmpty();
}
}
}
void
ThebesLayerD3D10::DrawRegion(const nsIntRegion &aRegion)
{
HRESULT hr;
nsIntRect visibleRect = mVisibleRegion.GetBounds();
if (!mD2DSurface) {
return;
}
nsRefPtr<gfxContext> context = new gfxContext(mD2DSurface);
nsIntRegionRectIterator iter(aRegion);
context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
context->NewPath();
const nsIntRect *iterRect;
while ((iterRect = iter.Next())) {
context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
}
context->Clip();
if (mD2DSurface->GetContentType() != gfxASurface::CONTENT_COLOR) {
context->SetOperator(gfxContext::OPERATOR_CLEAR);
context->Paint();
context->SetOperator(gfxContext::OPERATOR_OVER);
}
LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
}
void
ThebesLayerD3D10::CreateNewTexture(const gfxIntSize &aSize)
{
if (aSize.width == 0 || aSize.height == 0) {
// Nothing to do.
return;
}
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(mTexture));
if (FAILED(hr)) {
NS_WARNING("Failed to create new texture for ThebesLayerD3D10!");
return;
}
hr = device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
if (FAILED(hr)) {
NS_WARNING("Failed to create shader resource view for ThebesLayerD3D10.");
}
mD2DSurface = new gfxD2DSurface(mTexture, CanUseOpaqueSurface() ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
if (!mD2DSurface || mD2DSurface->CairoStatus()) {
NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
mD2DSurface = nsnull;
return;
}
}
} /* namespace layers */
} /* namespace mozilla */

View File

@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_THEBESLAYERD3D10_H
#define GFX_THEBESLAYERD3D10_H
#include "Layers.h"
#include "LayerManagerD3D10.h"
namespace mozilla {
namespace layers {
class ThebesLayerD3D10 : public ThebesLayer,
public LayerD3D10
{
public:
ThebesLayerD3D10(LayerManagerD3D10 *aManager);
virtual ~ThebesLayerD3D10();
/* Layer implementation */
void SetVisibleRegion(const nsIntRegion& aRegion);
/* ThebesLayer implementation */
void InvalidateRegion(const nsIntRegion& aRegion);
/* LayerD3D10 implementation */
Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void Validate();
virtual void LayerManagerDestroyed();
private:
/* Texture with our surface data */
nsRefPtr<ID3D10Texture2D> mTexture;
/* Shader resource view for our texture */
nsRefPtr<ID3D10ShaderResourceView> mSRView;
/* Checks if our D2D surface has the right content type */
void VerifyContentType();
/* This contains the thebes surface */
nsRefPtr<gfxASurface> mD2DSurface;
/* Have a region of our layer drawn */
void DrawRegion(const nsIntRegion &aRegion);
/* Create a new texture */
void CreateNewTexture(const gfxIntSize &aSize);
};
} /* layers */
} /* mozilla */
#endif /* GFX_THEBESLAYERD3D10_H */