mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 546515: Part 1: Add a layers backend based on Direct3D9. r=jrmuizel
This commit is contained in:
parent
8fb86df3e7
commit
5c0ef5136a
@ -122,7 +122,8 @@ class THEBES_API LayerManager {
|
||||
public:
|
||||
enum LayersBackend {
|
||||
LAYERS_BASIC = 0,
|
||||
LAYERS_OPENGL
|
||||
LAYERS_OPENGL,
|
||||
LAYERS_D3D9
|
||||
};
|
||||
|
||||
virtual ~LayerManager() {}
|
||||
|
@ -42,6 +42,7 @@ VPATH = \
|
||||
$(srcdir) \
|
||||
$(srcdir)/basic \
|
||||
$(srcdir)/opengl \
|
||||
$(srcdir)/d3d9 \
|
||||
$(NULL)
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
@ -52,6 +53,9 @@ LIBXUL_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
DEFINES += -DIMPL_THEBES
|
||||
ifdef MOZ_DEBUG
|
||||
DEFINES += -DD3D_DEBUG_INFO
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
BasicLayers.h \
|
||||
@ -70,6 +74,21 @@ CPPSRCS = \
|
||||
ImageLayerOGL.cpp \
|
||||
CanvasLayerOGL.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
ifndef WINCE
|
||||
EXPORTS += LayerManagerD3D9.h
|
||||
|
||||
CPPSRCS += \
|
||||
LayerManagerD3D9.cpp \
|
||||
ThebesLayerD3D9.cpp \
|
||||
ContainerLayerD3D9.cpp \
|
||||
ImageLayerD3D9.cpp \
|
||||
ColorLayerD3D9.cpp \
|
||||
CanvasLayerD3D9.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
231
gfx/layers/d3d9/CanvasLayerD3D9.cpp
Normal file
231
gfx/layers/d3d9/CanvasLayerD3D9.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
/* -*- 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 "CanvasLayerD3D9.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
CanvasLayerD3D9::~CanvasLayerD3D9()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayerD3D9::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;
|
||||
} else if (aData.mGLContext) {
|
||||
mGLContext = aData.mGLContext;
|
||||
mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied;
|
||||
mNeedsYFlip = PR_TRUE;
|
||||
} else {
|
||||
NS_ERROR("CanvasLayer created without mSurface or mGLContext?");
|
||||
}
|
||||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, 0,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayerD3D9::Updated(const nsIntRect& aRect)
|
||||
{
|
||||
if (!mTexture) {
|
||||
NS_WARNING("CanvasLayerD3D9::Updated called but no texture present!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGLContext) {
|
||||
// WebGL reads entire surface.
|
||||
D3DLOCKED_RECT r;
|
||||
mTexture->LockRect(0, &r, NULL, 0);
|
||||
|
||||
PRUint8 *destination;
|
||||
if (r.Pitch != mBounds.width * 4) {
|
||||
destination = new PRUint8[mBounds.width * mBounds.height * 4];
|
||||
} else {
|
||||
destination = (PRUint8*)r.pBits;
|
||||
}
|
||||
|
||||
// We have to flush to ensure that any buffered GL operations are
|
||||
// in the framebuffer before we read.
|
||||
mGLContext->fFlush();
|
||||
|
||||
// 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.
|
||||
mGLContext->fReadPixels(0, 0, mBounds.width, mBounds.height,
|
||||
LOCAL_GL_BGRA, LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
destination);
|
||||
|
||||
if (r.Pitch != mBounds.width * 4) {
|
||||
for (int y = 0; y < mBounds.height; y++) {
|
||||
memcpy((PRUint8*)r.pBits + r.Pitch * y,
|
||||
destination + mBounds.width * 4 * y,
|
||||
mBounds.width * 4);
|
||||
}
|
||||
delete [] destination;
|
||||
}
|
||||
mTexture->UnlockRect(0);
|
||||
} else if (mSurface) {
|
||||
RECT r;
|
||||
r.left = aRect.x;
|
||||
r.top = aRect.y;
|
||||
r.right = aRect.XMost();
|
||||
r.bottom = aRect.YMost();
|
||||
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
mTexture->LockRect(0, &lockedRect, &r, 0);
|
||||
|
||||
PRUint8 *startBits;
|
||||
PRUint32 sourceStride;
|
||||
|
||||
nsRefPtr<gfxImageSurface> sourceSurface;
|
||||
|
||||
if (mSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
|
||||
sourceSurface = static_cast<gfxWindowsSurface*>(mSurface.get())->GetImageSurface();
|
||||
startBits = sourceSurface->Data() + sourceSurface->Stride() * aRect.y +
|
||||
aRect.x * 4;
|
||||
sourceStride = sourceSurface->Stride();
|
||||
} else if (mSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
sourceSurface = static_cast<gfxImageSurface*>(sourceSurface.get());
|
||||
if (sourceSurface->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
sourceSurface->Format() != gfxASurface::ImageFormatRGB24)
|
||||
{
|
||||
mTexture->UnlockRect(0);
|
||||
return;
|
||||
}
|
||||
startBits = sourceSurface->Data() + sourceSurface->Stride() * aRect.y +
|
||||
aRect.x * 4;
|
||||
sourceStride = sourceSurface->Stride();
|
||||
} else {
|
||||
sourceSurface = new gfxImageSurface(gfxIntSize(aRect.width, aRect.height),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(sourceSurface);
|
||||
ctx->Translate(gfxPoint(-aRect.x, -aRect.y));
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(sourceSurface);
|
||||
ctx->Paint();
|
||||
startBits = sourceSurface->Data();
|
||||
sourceStride = sourceSurface->Stride();
|
||||
}
|
||||
|
||||
for (int y = 0; y < aRect.height; y++) {
|
||||
memcpy((PRUint8*)lockedRect.pBits + lockedRect.Pitch * y,
|
||||
startBits + sourceStride * y,
|
||||
aRect.width * 4);
|
||||
}
|
||||
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
CanvasLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_CANVAS;
|
||||
}
|
||||
|
||||
Layer*
|
||||
CanvasLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasLayerD3D9::RenderLayer()
|
||||
{
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we offset the quad half a pixel
|
||||
* to the top-left. We also flip the Y axis here, note we can only do this
|
||||
* because we are in CULL_NONE mode!
|
||||
*
|
||||
* See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)mBounds.width;
|
||||
if (mNeedsYFlip) {
|
||||
quadTransform[1][1] = (float)-mBounds.height;
|
||||
quadTransform[3][1] = (float)mBounds.height - 0.5f;
|
||||
} else {
|
||||
quadTransform[1][1] = (float)mBounds.height;
|
||||
quadTransform[3][1] = -0.5f;
|
||||
}
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = -0.5f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
if (!mGLBufferIsPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
}
|
||||
device()->SetTexture(0, mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
if (!mGLBufferIsPremultiplied) {
|
||||
device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
90
gfx/layers/d3d9/CanvasLayerD3D9.h
Normal file
90
gfx/layers/d3d9/CanvasLayerD3D9.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* -*- 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 "LayerManagerD3D9.h"
|
||||
#include "GLContext.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class THEBES_API CanvasLayerD3D9 :
|
||||
public CanvasLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
CanvasLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: CanvasLayer(aManager, NULL),
|
||||
LayerD3D9(aManager),
|
||||
mTexture(0),
|
||||
mGLBufferIsPremultiplied(PR_FALSE),
|
||||
mNeedsYFlip(PR_FALSE)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
~CanvasLayerD3D9();
|
||||
|
||||
// CanvasLayer implementation
|
||||
virtual void Initialize(const Data& aData);
|
||||
virtual void Updated(const nsIntRect& aRect);
|
||||
|
||||
// LayerD3D9 implementation
|
||||
virtual LayerType GetType();
|
||||
virtual Layer* GetLayer();
|
||||
virtual void RenderLayer();
|
||||
|
||||
protected:
|
||||
typedef mozilla::gl::GLContext GLContext;
|
||||
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<GLContext> mGLContext;
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
|
||||
nsIntRect mBounds;
|
||||
|
||||
PRPackedBool mGLBufferIsPremultiplied;
|
||||
PRPackedBool mNeedsYFlip;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_CANVASLAYERD3D9_H */
|
91
gfx/layers/d3d9/ColorLayerD3D9.cpp
Normal file
91
gfx/layers/d3d9/ColorLayerD3D9.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/* -*- 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 "ColorLayerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ColorLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_COLOR;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ColorLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
ColorLayerD3D9::RenderLayer()
|
||||
{
|
||||
// XXX we might be able to improve performance by using
|
||||
// IDirect3DDevice9::Clear
|
||||
|
||||
float quadTransform[4][4];
|
||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
||||
// Transform the quad to the size of the visible area.
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)visibleRect.width;
|
||||
quadTransform[1][1] = (float)visibleRect.height;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = (float)visibleRect.x;
|
||||
quadTransform[3][1] = (float)visibleRect.y;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float color[4];
|
||||
// color is premultiplied, so we need to adjust all channels
|
||||
color[0] = (float)(mColor.r * GetOpacity());
|
||||
color[1] = (float)(mColor.g * GetOpacity());
|
||||
color[2] = (float)(mColor.b * GetOpacity());
|
||||
color[3] = (float)(mColor.a * GetOpacity());
|
||||
|
||||
device()->SetPixelShaderConstantF(0, color, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::SOLIDCOLORLAYER);
|
||||
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
74
gfx/layers/d3d9/ColorLayerD3D9.h
Normal file
74
gfx/layers/d3d9/ColorLayerD3D9.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- 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 ***** */
|
||||
|
||||
#ifndef GFX_COLORLAYERD3D9_H
|
||||
#define GFX_COLORLAYERD3D9_H
|
||||
|
||||
#include "LayerManagerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class THEBES_API ColorLayerD3D9 : public ColorLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ColorLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ColorLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion) { mVisibleRegion = aRegion; }
|
||||
|
||||
// LayerD3D9 Implementation
|
||||
virtual LayerType GetType();
|
||||
|
||||
virtual Layer* GetLayer();
|
||||
|
||||
virtual void RenderLayer();
|
||||
|
||||
protected:
|
||||
nsIntRegion mVisibleRegion;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_COLORLAYERD3D9_H */
|
252
gfx/layers/d3d9/ContainerLayerD3D9.cpp
Normal file
252
gfx/layers/d3d9/ContainerLayerD3D9.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
/* -*- 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 "ContainerLayerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ContainerLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ContainerLayerD3D9::GetVisibleRect()
|
||||
{
|
||||
return mVisibleRect;
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
mVisibleRect = aRegion.GetBounds();
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::InsertAfter(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
LayerD3D9 *newChild = static_cast<LayerD3D9*>(aChild->ImplData());
|
||||
aChild->SetParent(this);
|
||||
if (!aAfter) {
|
||||
LayerD3D9 *oldFirstChild = GetFirstChildD3D9();
|
||||
mFirstChild = newChild->GetLayer();
|
||||
newChild->SetNextSibling(oldFirstChild);
|
||||
return;
|
||||
}
|
||||
for (LayerD3D9 *child = GetFirstChildD3D9();
|
||||
child; child = child->GetNextSibling()) {
|
||||
if (aAfter == child->GetLayer()) {
|
||||
LayerD3D9 *oldNextSibling = child->GetNextSibling();
|
||||
child->SetNextSibling(newChild);
|
||||
child->GetNextSibling()->SetNextSibling(oldNextSibling);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_WARNING("Failed to find aAfter layer!");
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::RemoveChild(Layer *aChild)
|
||||
{
|
||||
if (GetFirstChild() == aChild) {
|
||||
mFirstChild = GetFirstChildD3D9()->GetNextSibling() ?
|
||||
GetFirstChildD3D9()->GetNextSibling()->GetLayer() : nsnull;
|
||||
return;
|
||||
}
|
||||
LayerD3D9 *lastChild = NULL;
|
||||
for (LayerD3D9 *child = GetFirstChildD3D9(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (child->GetLayer() == aChild) {
|
||||
// We're sure this is not our first child. So lastChild != NULL.
|
||||
lastChild->SetNextSibling(child->GetNextSibling());
|
||||
child->SetNextSibling(NULL);
|
||||
child->GetLayer()->SetParent(NULL);
|
||||
return;
|
||||
}
|
||||
lastChild = child;
|
||||
}
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ContainerLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_CONTAINER;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ContainerLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
LayerD3D9*
|
||||
ContainerLayerD3D9::GetFirstChildD3D9()
|
||||
{
|
||||
if (!mFirstChild) {
|
||||
return nsnull;
|
||||
}
|
||||
return static_cast<LayerD3D9*>(mFirstChild->ImplData());
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayerD3D9::RenderLayer()
|
||||
{
|
||||
float opacity = GetOpacity();
|
||||
nsRefPtr<IDirect3DSurface9> previousRenderTarget;
|
||||
nsRefPtr<IDirect3DTexture9> renderTexture;
|
||||
float previousRenderTargetOffset[4];
|
||||
float renderTargetOffset[] = { 0, 0, 0, 0 };
|
||||
float oldViewMatrix[4][4];
|
||||
|
||||
PRBool useIntermediate = (opacity != 1.0 || !mTransform.IsIdentity());
|
||||
|
||||
if (useIntermediate) {
|
||||
device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
|
||||
device()->CreateTexture(mVisibleRect.width, mVisibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
|
||||
NULL);
|
||||
nsRefPtr<IDirect3DSurface9> renderSurface;
|
||||
renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
|
||||
device()->SetRenderTarget(0, renderSurface);
|
||||
device()->GetVertexShaderConstantF(12, previousRenderTargetOffset, 1);
|
||||
renderTargetOffset[0] = (float)GetVisibleRect().x;
|
||||
renderTargetOffset[1] = (float)GetVisibleRect().y;
|
||||
device()->SetVertexShaderConstantF(12, renderTargetOffset, 1);
|
||||
|
||||
float viewMatrix[4][4];
|
||||
/*
|
||||
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
|
||||
* <1.0, -1.0> bottomright)
|
||||
*/
|
||||
memset(&viewMatrix, 0, sizeof(viewMatrix));
|
||||
viewMatrix[0][0] = 2.0f / mVisibleRect.width;
|
||||
viewMatrix[1][1] = -2.0f / mVisibleRect.height;
|
||||
viewMatrix[2][2] = 1.0f;
|
||||
viewMatrix[3][0] = -1.0f;
|
||||
viewMatrix[3][1] = 1.0f;
|
||||
viewMatrix[3][3] = 1.0f;
|
||||
|
||||
device()->GetVertexShaderConstantF(8, &oldViewMatrix[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(8, &viewMatrix[0][0], 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Render this container's contents.
|
||||
*/
|
||||
LayerD3D9 *layerToRender = GetFirstChildD3D9();
|
||||
while (layerToRender) {
|
||||
const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect();
|
||||
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 {
|
||||
if (useIntermediate) {
|
||||
r.left = 0;
|
||||
r.top = 0;
|
||||
} else {
|
||||
r.left = GetVisibleRect().x;
|
||||
r.top = GetVisibleRect().y;
|
||||
}
|
||||
r.right = r.left + GetVisibleRect().width;
|
||||
r.bottom = r.top + GetVisibleRect().height;
|
||||
}
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> renderSurface;
|
||||
device()->GetRenderTarget(0, getter_AddRefs(renderSurface));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
renderSurface->GetDesc(&desc);
|
||||
|
||||
r.left = NS_MAX<LONG>(0, r.left);
|
||||
r.top = NS_MAX<LONG>(0, r.top);
|
||||
r.bottom = NS_MIN<LONG>(r.bottom, desc.Height);
|
||||
r.right = NS_MIN<LONG>(r.right, desc.Width);
|
||||
|
||||
device()->SetScissorRect(&r);
|
||||
|
||||
layerToRender->RenderLayer();
|
||||
layerToRender = layerToRender->GetNextSibling();
|
||||
}
|
||||
|
||||
if (useIntermediate) {
|
||||
device()->SetRenderTarget(0, previousRenderTarget);
|
||||
device()->SetVertexShaderConstantF(12, previousRenderTargetOffset, 1);
|
||||
device()->SetVertexShaderConstantF(8, &oldViewMatrix[0][0], 4);
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we offset the quad half a pixel
|
||||
* to the top-left.
|
||||
*
|
||||
* See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)GetVisibleRect().width;
|
||||
quadTransform[1][1] = (float)GetVisibleRect().height;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = (float)GetVisibleRect().x - 0.5f;
|
||||
quadTransform[3][1] = (float)GetVisibleRect().y - 0.5f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacityVector[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacityVector[0] = opacity;
|
||||
device()->SetPixelShaderConstantF(0, opacityVector, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, renderTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
80
gfx/layers/d3d9/ContainerLayerD3D9.h
Normal file
80
gfx/layers/d3d9/ContainerLayerD3D9.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* -*- 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_CONTAINERLAYERD3D9_H
|
||||
#define GFX_CONTAINERLAYERD3D9_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D9.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ContainerLayerD3D9 : public ContainerLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ContainerLayerD3D9(LayerManagerD3D9 *aManager);
|
||||
|
||||
const nsIntRect &GetVisibleRect();
|
||||
|
||||
/* ContainerLayer implementation */
|
||||
void SetVisibleRegion(const nsIntRegion& aRegion);
|
||||
|
||||
void InsertAfter(Layer* aChild, Layer* aAfter);
|
||||
|
||||
void RemoveChild(Layer* aChild);
|
||||
|
||||
/* LayerD3D9 implementation */
|
||||
LayerType GetType();
|
||||
|
||||
Layer* GetLayer();
|
||||
|
||||
LayerD3D9* GetFirstChildD3D9();
|
||||
|
||||
PRBool IsEmpty();
|
||||
|
||||
void RenderLayer();
|
||||
|
||||
private:
|
||||
nsIntRect mVisibleRect;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_CONTAINERLAYERD3D9_H */
|
463
gfx/layers/d3d9/ImageLayerD3D9.cpp
Normal file
463
gfx/layers/d3d9/ImageLayerD3D9.cpp
Normal file
@ -0,0 +1,463 @@
|
||||
/* -*- 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 ***** */
|
||||
|
||||
#include "ImageLayerD3D9.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "yuv_convert.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using mozilla::MutexAutoLock;
|
||||
|
||||
ImageContainerD3D9::ImageContainerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ImageContainer(aManager)
|
||||
, mActiveImageLock("mozilla.layers.ImageContainerD3D9.mActiveImageLock")
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<Image>
|
||||
ImageContainerD3D9::CreateImage(const Image::Format *aFormats,
|
||||
PRUint32 aNumFormats)
|
||||
{
|
||||
if (!aNumFormats) {
|
||||
return nsnull;
|
||||
}
|
||||
nsRefPtr<Image> img;
|
||||
if (aFormats[0] == Image::PLANAR_YCBCR) {
|
||||
img = new PlanarYCbCrImageD3D9(static_cast<LayerManagerD3D9*>(mManager));
|
||||
} else if (aFormats[0] == Image::CAIRO_SURFACE) {
|
||||
img = new CairoImageD3D9(static_cast<LayerManagerD3D9*>(mManager));
|
||||
}
|
||||
return img.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ImageContainerD3D9::SetCurrentImage(Image *aImage)
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
|
||||
mActiveImage = aImage;
|
||||
}
|
||||
|
||||
already_AddRefed<Image>
|
||||
ImageContainerD3D9::GetCurrentImage()
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
|
||||
nsRefPtr<Image> retval = mActiveImage;
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
ImageContainerD3D9::GetCurrentAsSurface(gfxIntSize *aSize)
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
if (!mActiveImage) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
|
||||
PlanarYCbCrImageD3D9 *yuvImage =
|
||||
static_cast<PlanarYCbCrImageD3D9*>(mActiveImage.get());
|
||||
if (yuvImage->HasData()) {
|
||||
*aSize = yuvImage->mSize;
|
||||
}
|
||||
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
|
||||
CairoImageD3D9 *cairoImage =
|
||||
static_cast<CairoImageD3D9*>(mActiveImage.get());
|
||||
*aSize = cairoImage->mSize;
|
||||
}
|
||||
|
||||
return static_cast<ImageD3D9*>(mActiveImage->GetImplData())->GetAsSurface();
|
||||
}
|
||||
|
||||
gfxIntSize
|
||||
ImageContainerD3D9::GetCurrentSize()
|
||||
{
|
||||
MutexAutoLock lock(mActiveImageLock);
|
||||
if (!mActiveImage) {
|
||||
return gfxIntSize(0,0);
|
||||
}
|
||||
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
|
||||
PlanarYCbCrImageD3D9 *yuvImage =
|
||||
static_cast<PlanarYCbCrImageD3D9*>(mActiveImage.get());
|
||||
if (!yuvImage->HasData()) {
|
||||
return gfxIntSize(0,0);
|
||||
}
|
||||
return yuvImage->mSize;
|
||||
|
||||
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
|
||||
CairoImageD3D9 *cairoImage =
|
||||
static_cast<CairoImageD3D9*>(mActiveImage.get());
|
||||
return cairoImage->mSize;
|
||||
}
|
||||
|
||||
return gfxIntSize(0,0);
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ImageLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_IMAGE;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ImageLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
ImageLayerD3D9::RenderLayer()
|
||||
{
|
||||
if (!GetContainer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Image> image = GetContainer()->GetCurrentImage();
|
||||
|
||||
if (image->GetFormat() == Image::PLANAR_YCBCR) {
|
||||
PlanarYCbCrImageD3D9 *yuvImage =
|
||||
static_cast<PlanarYCbCrImageD3D9*>(image.get());
|
||||
|
||||
if (!yuvImage->HasData()) {
|
||||
return;
|
||||
}
|
||||
yuvImage->AllocateTextures();
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we extend the quad half a pixel
|
||||
* beyond all edges.
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)yuvImage->mSize.width + 0.5f;
|
||||
quadTransform[1][1] = (float)yuvImage->mSize.height + 0.5f;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will
|
||||
* only use the the first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::YCBCRLAYER);
|
||||
|
||||
device()->SetTexture(0, yuvImage->mYTexture);
|
||||
device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetTexture(1, yuvImage->mCbTexture);
|
||||
device()->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetTexture(2, yuvImage->mCrTexture);
|
||||
device()->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device()->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
} else if (image->GetFormat() == Image::CAIRO_SURFACE) {
|
||||
CairoImageD3D9 *cairoImage =
|
||||
static_cast<CairoImageD3D9*>(image.get());
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we extend the quad half a pixel
|
||||
* beyond all edges.
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)cairoImage->mSize.width + 0.5f;
|
||||
quadTransform[1][1] = (float)cairoImage->mSize.height + 0.5f;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will
|
||||
* only use the the first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, cairoImage->mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9(mozilla::layers::LayerManagerD3D9* aManager)
|
||||
: PlanarYCbCrImage(static_cast<ImageD3D9*>(this))
|
||||
, mManager(aManager)
|
||||
, mHasData(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageD3D9::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
// 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;
|
||||
} else if (aData.mYSize.width / 2 == aData.mCbCrSize.width &&
|
||||
aData.mYSize.height == aData.mCbCrSize.height) {
|
||||
// YV16 format
|
||||
width_shift = 1;
|
||||
height_shift = 0;
|
||||
} else if (aData.mYSize.width / 2 == aData.mCbCrSize.width &&
|
||||
aData.mYSize.height / 2 == aData.mCbCrSize.height ) {
|
||||
// YV12 format
|
||||
width_shift = 1;
|
||||
height_shift = 1;
|
||||
} else {
|
||||
NS_ERROR("YCbCr format not supported");
|
||||
}
|
||||
|
||||
mData = aData;
|
||||
mData.mCbCrStride = mData.mCbCrSize.width = aData.mPicSize.width >> width_shift;
|
||||
mData.mCbCrSize.height = aData.mPicSize.height >> height_shift;
|
||||
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;
|
||||
|
||||
mData.mCrChannel = new PRUint8[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;
|
||||
|
||||
mHasData = PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageD3D9::AllocateTextures()
|
||||
{
|
||||
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
PRUint8* src;
|
||||
PRUint8* dest;
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mYTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mYChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mYSize.height; h++) {
|
||||
memcpy(dest, src, mData.mYSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mYStride;
|
||||
}
|
||||
|
||||
mYTexture->UnlockRect(0);
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCbTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCbChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCbTexture->UnlockRect(0);
|
||||
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCrTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCrChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCrTexture->UnlockRect(0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PlanarYCbCrImageD3D9::FreeTextures()
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
PlanarYCbCrImageD3D9::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(),
|
||||
gfx::YV12);
|
||||
|
||||
return imageSurface.forget().get();
|
||||
}
|
||||
|
||||
CairoImageD3D9::~CairoImageD3D9()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CairoImageD3D9::SetData(const CairoImage::Data &aData)
|
||||
{
|
||||
mSize = aData.mSize;
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface(aData.mSize, gfxASurface::ImageFormatARGB32);
|
||||
|
||||
nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
|
||||
|
||||
context->SetSource(aData.mSurface);
|
||||
context->Paint();
|
||||
|
||||
//XXX: make sure we're using the correct usage flags
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
/* lock the entire texture */
|
||||
mTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
PRUint8* src = imageSurface->Data();
|
||||
//FIX cast
|
||||
PRUint8* dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data. If we don't need to do any swaping we can
|
||||
// use memcpy
|
||||
for (int i=0; i<aData.mSize.width*aData.mSize.height; i++) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
CairoImageD3D9::GetAsSurface()
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
155
gfx/layers/d3d9/ImageLayerD3D9.h
Normal file
155
gfx/layers/d3d9/ImageLayerD3D9.h
Normal 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_IMAGELAYERD3D9_H
|
||||
#define GFX_IMAGELAYERD3D9_H
|
||||
|
||||
#include "LayerManagerD3D9.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class THEBES_API ImageContainerD3D9 : public ImageContainer
|
||||
{
|
||||
public:
|
||||
ImageContainerD3D9(LayerManagerD3D9 *aManager);
|
||||
virtual ~ImageContainerD3D9() {}
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
typedef mozilla::Mutex Mutex;
|
||||
|
||||
nsRefPtr<Image> mActiveImage;
|
||||
|
||||
Mutex mActiveImageLock;
|
||||
};
|
||||
|
||||
class THEBES_API ImageLayerD3D9 : public ImageLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ImageLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ImageLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
}
|
||||
|
||||
// LayerD3D9 Implementation
|
||||
virtual LayerType GetType();
|
||||
|
||||
virtual Layer* GetLayer();
|
||||
|
||||
virtual void RenderLayer();
|
||||
};
|
||||
|
||||
class THEBES_API ImageD3D9
|
||||
{
|
||||
public:
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() = 0;
|
||||
};
|
||||
|
||||
class THEBES_API PlanarYCbCrImageD3D9 : public PlanarYCbCrImage,
|
||||
public ImageD3D9
|
||||
{
|
||||
public:
|
||||
PlanarYCbCrImageD3D9(LayerManagerD3D9 *aManager);
|
||||
|
||||
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();
|
||||
/*
|
||||
* XXX
|
||||
* Free the textures, we call this from the main thread when we're done
|
||||
* drawing this frame. We cannot free this from the constructor since it may
|
||||
* be destroyed off the main-thread and might not be able to properly clean
|
||||
* up its textures
|
||||
*/
|
||||
void FreeTextures();
|
||||
PRBool HasData() { return mHasData; }
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
LayerManagerD3D9 *mManager;
|
||||
Data mData;
|
||||
gfxIntSize mSize;
|
||||
nsRefPtr<IDirect3DTexture9> mYTexture;
|
||||
nsRefPtr<IDirect3DTexture9> mCrTexture;
|
||||
nsRefPtr<IDirect3DTexture9> mCbTexture;
|
||||
PRPackedBool mHasData;
|
||||
};
|
||||
|
||||
|
||||
class THEBES_API CairoImageD3D9 : public CairoImage,
|
||||
public ImageD3D9
|
||||
{
|
||||
public:
|
||||
CairoImageD3D9(LayerManagerD3D9 *aManager)
|
||||
: CairoImage(static_cast<ImageD3D9*>(this))
|
||||
, mManager(aManager)
|
||||
{ }
|
||||
~CairoImageD3D9();
|
||||
|
||||
virtual void SetData(const Data &aData);
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
gfxIntSize mSize;
|
||||
LayerManagerD3D9 *mManager;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_IMAGELAYERD3D9_H */
|
578
gfx/layers/d3d9/LayerManagerD3D9.cpp
Normal file
578
gfx/layers/d3d9/LayerManagerD3D9.cpp
Normal file
@ -0,0 +1,578 @@
|
||||
/* -*- 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 "LayerManagerD3D9.h"
|
||||
|
||||
#include "ThebesLayerD3D9.h"
|
||||
#include "ContainerLayerD3D9.h"
|
||||
#include "ImageLayerD3D9.h"
|
||||
#include "ColorLayerD3D9.h"
|
||||
#include "CanvasLayerD3D9.h"
|
||||
|
||||
#include "LayerManagerD3D9Shaders.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
struct vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
||||
IDirect3D9 *LayerManagerD3D9::mD3D9 = NULL;
|
||||
|
||||
typedef IDirect3D9* (WINAPI*Direct3DCreate9Func)(
|
||||
UINT SDKVersion
|
||||
);
|
||||
|
||||
|
||||
LayerManagerD3D9::LayerManagerD3D9(nsIWidget *aWidget)
|
||||
{
|
||||
mWidget = aWidget;
|
||||
mCurrentCallbackInfo.Callback = NULL;
|
||||
mCurrentCallbackInfo.CallbackData = NULL;
|
||||
}
|
||||
|
||||
LayerManagerD3D9::~LayerManagerD3D9()
|
||||
{
|
||||
}
|
||||
|
||||
#define HAS_CAP(a, b) (((a) & (b)) == (b))
|
||||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::Initialize()
|
||||
{
|
||||
if (!mD3D9) {
|
||||
Direct3DCreate9Func d3d9create = (Direct3DCreate9Func)
|
||||
GetProcAddress(LoadLibraryW(L"d3d9.dll"), "Direct3DCreate9");
|
||||
if (!d3d9create) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
mD3D9 = d3d9create(D3D_SDK_VERSION);
|
||||
if (!mD3D9) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
HRESULT hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
NULL,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
D3DCREATE_MULTITHREADED |
|
||||
D3DCREATE_MIXED_VERTEXPROCESSING,
|
||||
&pp,
|
||||
getter_AddRefs(mDevice));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!VerifyCaps()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexShader((DWORD*)LayerQuadVS,
|
||||
getter_AddRefs(mLayerVS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)RGBShaderPS,
|
||||
getter_AddRefs(mRGBPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)YCbCrShaderPS,
|
||||
getter_AddRefs(mYCbCrPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreatePixelShader((DWORD*)SolidColorShaderPS,
|
||||
getter_AddRefs(mSolidColorPS));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hr = mDevice->CreateVertexBuffer(sizeof(vertex) * 4,
|
||||
0,
|
||||
0,
|
||||
D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mVB),
|
||||
NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
vertex *vertices;
|
||||
hr = mVB->Lock(0, 0, (void**)&vertices, 0);
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
vertices[0].x = vertices[0].y = 0;
|
||||
vertices[1].x = 1; vertices[1].y = 0;
|
||||
vertices[2].x = 0; vertices[2].y = 1;
|
||||
vertices[3].x = 1; vertices[3].y = 1;
|
||||
|
||||
mVB->Unlock();
|
||||
|
||||
hr = mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
D3DVERTEXELEMENT9 elements[] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
|
||||
D3DDECLUSAGE_POSITION, 0 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
mDevice->CreateVertexDeclaration(elements, getter_AddRefs(mVD));
|
||||
|
||||
SetupRenderState();
|
||||
|
||||
nsCOMPtr<nsIConsoleService>
|
||||
console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 identifier;
|
||||
mD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
|
||||
|
||||
if (console) {
|
||||
nsString msg;
|
||||
msg +=
|
||||
NS_LITERAL_STRING("Direct3D 9 LayerManager Initialized Succesfully.\nDriver: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Driver));
|
||||
msg += NS_LITERAL_STRING("\nDescription: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsDependentCString((const char*)identifier.Description));
|
||||
msg += NS_LITERAL_STRING("\nVersion: ");
|
||||
msg += NS_ConvertUTF8toUTF16(
|
||||
nsPrintfCString("%d.%d.%d.%d",
|
||||
HIWORD(identifier.DriverVersion.HighPart),
|
||||
LOWORD(identifier.DriverVersion.HighPart),
|
||||
HIWORD(identifier.DriverVersion.LowPart),
|
||||
LOWORD(identifier.DriverVersion.LowPart)));
|
||||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetClippingRegion(const nsIntRegion &aClippingRegion)
|
||||
{
|
||||
mClippingRegion = aClippingRegion;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::BeginTransaction()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::BeginTransactionWithTarget(gfxContext *aTarget)
|
||||
{
|
||||
mTarget = aTarget;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::EndConstruction()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
mCurrentCallbackInfo.Callback = aCallback;
|
||||
mCurrentCallbackInfo.CallbackData = aCallbackData;
|
||||
Render();
|
||||
/* Clean this out for sanity */
|
||||
mCurrentCallbackInfo.Callback = NULL;
|
||||
mCurrentCallbackInfo.CallbackData = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetRoot(Layer *aLayer)
|
||||
{
|
||||
mRootLayer = static_cast<LayerD3D9*>(aLayer->ImplData());
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
LayerManagerD3D9::CreateThebesLayer()
|
||||
{
|
||||
nsRefPtr<ThebesLayer> layer = new ThebesLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
LayerManagerD3D9::CreateContainerLayer()
|
||||
{
|
||||
nsRefPtr<ContainerLayer> layer = new ContainerLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
LayerManagerD3D9::CreateImageLayer()
|
||||
{
|
||||
nsRefPtr<ImageLayer> layer = new ImageLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ColorLayer>
|
||||
LayerManagerD3D9::CreateColorLayer()
|
||||
{
|
||||
nsRefPtr<ColorLayer> layer = new ColorLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
LayerManagerD3D9::CreateCanvasLayer()
|
||||
{
|
||||
nsRefPtr<CanvasLayer> layer = new CanvasLayerD3D9(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer>
|
||||
LayerManagerD3D9::CreateImageContainer()
|
||||
{
|
||||
nsRefPtr<ImageContainer> container = new ImageContainerD3D9(this);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetShaderMode(ShaderMode aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case RGBLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mRGBPS);
|
||||
break;
|
||||
case YCBCRLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mYCbCrPS);
|
||||
break;
|
||||
case SOLIDCOLORLAYER:
|
||||
mDevice->SetVertexShader(mLayerVS);
|
||||
mDevice->SetPixelShader(mSolidColorPS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::Render()
|
||||
{
|
||||
if (!SetupBackBuffer()) {
|
||||
return;
|
||||
}
|
||||
SetupPipeline();
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
|
||||
mDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0, 0);
|
||||
|
||||
mDevice->BeginScene();
|
||||
|
||||
if (mRootLayer) {
|
||||
const nsIntRect *clipRect = mRootLayer->GetLayer()->GetClipRect();
|
||||
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;
|
||||
}
|
||||
mDevice->SetScissorRect(&r);
|
||||
|
||||
mRootLayer->RenderLayer();
|
||||
}
|
||||
|
||||
mDevice->EndScene();
|
||||
|
||||
if (!mTarget) {
|
||||
const nsIntRect *r;
|
||||
for (nsIntRegionRectIterator iter(mClippingRegion);
|
||||
(r = iter.Next()) != nsnull;) {
|
||||
RECT rect;
|
||||
rect.left = r->x;
|
||||
rect.top = r->y;
|
||||
rect.right = r->XMost();
|
||||
rect.bottom = r->YMost();
|
||||
|
||||
mDevice->Present(&rect, &rect, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
PaintToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetupPipeline()
|
||||
{
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
|
||||
float viewMatrix[4][4];
|
||||
/*
|
||||
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
|
||||
* <1.0, -1.0> bottomright)
|
||||
*/
|
||||
memset(&viewMatrix, 0, sizeof(viewMatrix));
|
||||
viewMatrix[0][0] = 2.0f / rect.width;
|
||||
viewMatrix[1][1] = -2.0f / rect.height;
|
||||
viewMatrix[2][2] = 1.0f;
|
||||
viewMatrix[3][0] = -1.0f;
|
||||
viewMatrix[3][1] = 1.0f;
|
||||
viewMatrix[3][3] = 1.0f;
|
||||
|
||||
HRESULT hr = mDevice->SetVertexShaderConstantF(8, &viewMatrix[0][0], 4);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to set projection shader constant!");
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::SetupBackBuffer()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuffer;
|
||||
mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuffer));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
nsIntRect rect;
|
||||
mWidget->GetBounds(rect);
|
||||
backBuffer->GetDesc(&desc);
|
||||
|
||||
HRESULT hr = mDevice->TestCooperativeLevel();
|
||||
|
||||
/* The device is lost or something else is wrong, failure */
|
||||
if (FAILED(hr) && hr != D3DERR_DEVICENOTRESET) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the backbuffer is the right size, and the device is not lost, we can
|
||||
* safely render without doing anything.
|
||||
*/
|
||||
if ((desc.Width == rect.width && desc.Height == rect.height) &&
|
||||
SUCCEEDED(hr)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our device is lost or our backbuffer needs resizing, start by clearing
|
||||
* out all D3DPOOL_DEFAULT surfaces.
|
||||
*/
|
||||
for(unsigned int i = 0; i < mThebesLayers.Length(); i++) {
|
||||
mThebesLayers[i]->CleanResources();
|
||||
}
|
||||
|
||||
backBuffer = NULL;
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
hr = mDevice->Reset(&pp);
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SetupRenderState();
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::PaintToTarget()
|
||||
{
|
||||
nsRefPtr<IDirect3DSurface9> backBuff;
|
||||
nsRefPtr<IDirect3DSurface9> destSurf;
|
||||
mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
|
||||
getter_AddRefs(backBuff));
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
backBuff->GetDesc(&desc);
|
||||
|
||||
mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(destSurf), NULL);
|
||||
|
||||
mDevice->GetRenderTargetData(backBuff, destSurf);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
destSurf->LockRect(&rect, NULL, D3DLOCK_READONLY);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface((unsigned char*)rect.pBits,
|
||||
gfxIntSize(desc.Width, desc.Height),
|
||||
rect.Pitch,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mTarget->SetSource(imageSurface);
|
||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
mTarget->Paint();
|
||||
destSurf->UnlockRect();
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerD3D9::SetupRenderState()
|
||||
{
|
||||
mDevice->SetStreamSource(0, mVB, 0, sizeof(vertex));
|
||||
mDevice->SetVertexDeclaration(mVD);
|
||||
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
mDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
PRBool
|
||||
LayerManagerD3D9::VerifyCaps()
|
||||
{
|
||||
D3DCAPS9 caps;
|
||||
HRESULT hr = mDevice->GetDeviceCaps(&caps);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.DevCaps, D3DDEVCAPS_TEXTUREVIDEOMEMORY)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.SrcBlendCaps, D3DPBLENDCAPS_ONE) ||
|
||||
LACKS_CAP(caps.SrcBlendCaps, D3DBLEND_SRCALPHA) ||
|
||||
LACKS_CAP(caps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_ALPHA) ||
|
||||
HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_SQUAREONLY) ||
|
||||
(HAS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_POW2) &&
|
||||
LACKS_CAP(caps.TextureCaps, D3DPTEXTURECAPS_NONPOW2CONDITIONAL))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MAGFLINEAR) ||
|
||||
LACKS_CAP(caps.TextureFilterCaps, D3DPTFILTERCAPS_MINFLINEAR)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (LACKS_CAP(caps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (caps.MaxTextureHeight < 4096 ||
|
||||
caps.MaxTextureWidth < 4096) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if ((caps.PixelShaderVersion & 0xffff) < 0x200 ||
|
||||
(caps.VertexShaderVersion & 0xffff) < 0x200) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
LayerD3D9::LayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: mD3DManager(aManager)
|
||||
, mNextSibling(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LayerD3D9*
|
||||
LayerD3D9::GetNextSibling()
|
||||
{
|
||||
return mNextSibling;
|
||||
}
|
||||
|
||||
void
|
||||
LayerD3D9::SetNextSibling(LayerD3D9 *aNextSibling)
|
||||
{
|
||||
mNextSibling = aNextSibling;
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
239
gfx/layers/d3d9/LayerManagerD3D9.h
Normal file
239
gfx/layers/d3d9/LayerManagerD3D9.h
Normal file
@ -0,0 +1,239 @@
|
||||
/* -*- 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_LAYERMANAGERD3D9_H
|
||||
#define GFX_LAYERMANAGERD3D9_H
|
||||
|
||||
#include "Layers.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class LayerD3D9;
|
||||
class ThebesLayerD3D9;
|
||||
|
||||
/*
|
||||
* This is the LayerManager used for Direct3D 9. For now this will render on
|
||||
* the main thread.
|
||||
*/
|
||||
class THEBES_API LayerManagerD3D9 : public LayerManager {
|
||||
public:
|
||||
LayerManagerD3D9(nsIWidget *aWidget);
|
||||
virtual ~LayerManagerD3D9();
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
PRBool Initialize();
|
||||
|
||||
/*
|
||||
* Sets the clipping region for this layer manager. This is important on
|
||||
* windows because using OGL we no longer have GDI's native clipping. Therefor
|
||||
* widget must tell us what part of the screen is being invalidated,
|
||||
* and we should clip to this.
|
||||
*
|
||||
* \param aClippingRegion Region to clip to. Setting an empty region
|
||||
* will disable clipping.
|
||||
*/
|
||||
void SetClippingRegion(const nsIntRegion& aClippingRegion);
|
||||
|
||||
/*
|
||||
* LayerManager implementation.
|
||||
*/
|
||||
void BeginTransaction();
|
||||
|
||||
void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
|
||||
void EndConstruction();
|
||||
|
||||
struct CallbackInfo {
|
||||
DrawThebesLayerCallback Callback;
|
||||
void *CallbackData;
|
||||
};
|
||||
|
||||
void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
|
||||
const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; }
|
||||
|
||||
void SetRoot(Layer* aLayer);
|
||||
|
||||
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 LayersBackend GetBackendType() { return LAYERS_D3D9; }
|
||||
|
||||
/*
|
||||
* Helper methods.
|
||||
*/
|
||||
void SetClippingEnabled(PRBool aEnabled);
|
||||
|
||||
IDirect3DDevice9 *device() const { return mDevice; }
|
||||
|
||||
enum ShaderMode {
|
||||
RGBLAYER,
|
||||
YCBCRLAYER,
|
||||
SOLIDCOLORLAYER
|
||||
};
|
||||
|
||||
void SetShaderMode(ShaderMode aMode);
|
||||
|
||||
nsTArray<ThebesLayerD3D9*> mThebesLayers;
|
||||
|
||||
private:
|
||||
/* Direct3D9 instance */
|
||||
static IDirect3D9 *mD3D9;
|
||||
|
||||
/* Widget associated with this layer manager */
|
||||
nsIWidget *mWidget;
|
||||
/*
|
||||
* Context target, NULL when drawing directly to our swap chain.
|
||||
*/
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
nsRefPtr<IDirect3DDevice9> mDevice;
|
||||
|
||||
/* Vertex shader used for layer quads */
|
||||
nsRefPtr<IDirect3DVertexShader9> mLayerVS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mRGBPS;
|
||||
|
||||
/* Pixel shader used for RGB textures */
|
||||
nsRefPtr<IDirect3DPixelShader9> mYCbCrPS;
|
||||
|
||||
/* Pixel shader used for solid colors */
|
||||
nsRefPtr<IDirect3DPixelShader9> mSolidColorPS;
|
||||
|
||||
/* Vertex buffer containing our basic vertex structure */
|
||||
nsRefPtr<IDirect3DVertexBuffer9> mVB;
|
||||
|
||||
/* Our vertex declaration */
|
||||
nsRefPtr<IDirect3DVertexDeclaration9> mVD;
|
||||
|
||||
/* Current root layer. */
|
||||
LayerD3D9 *mRootLayer;
|
||||
|
||||
/* Callback info for current transaction */
|
||||
CallbackInfo mCurrentCallbackInfo;
|
||||
|
||||
/*
|
||||
* Region we're clipping our current drawing to.
|
||||
*/
|
||||
nsIntRegion mClippingRegion;
|
||||
/*
|
||||
* Render the current layer tree to the active target.
|
||||
*/
|
||||
void Render();
|
||||
/*
|
||||
* Setup the pipeline.
|
||||
*/
|
||||
void SetupPipeline();
|
||||
/*
|
||||
* Setup the backbuffer.
|
||||
*
|
||||
* \return PR_TRUE if setup was succesful
|
||||
*/
|
||||
PRBool SetupBackBuffer();
|
||||
/*
|
||||
* Setup the render state for the surface.
|
||||
*/
|
||||
void SetupRenderState();
|
||||
/*
|
||||
* Copies the content of our backbuffer to the set transaction target.
|
||||
*/
|
||||
void PaintToTarget();
|
||||
/*
|
||||
* Verifies all required device capabilities are present.
|
||||
*/
|
||||
PRBool VerifyCaps();
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* General information and tree management for OGL layers.
|
||||
*/
|
||||
class LayerD3D9
|
||||
{
|
||||
public:
|
||||
LayerD3D9(LayerManagerD3D9 *aManager);
|
||||
|
||||
enum LayerType { TYPE_THEBES, TYPE_CONTAINER, TYPE_IMAGE, TYPE_COLOR,
|
||||
TYPE_CANVAS };
|
||||
|
||||
virtual LayerType GetType() = 0;
|
||||
|
||||
LayerD3D9 *GetNextSibling();
|
||||
virtual LayerD3D9 *GetFirstChildD3D9() { return nsnull; }
|
||||
|
||||
void SetNextSibling(LayerD3D9 *aParent);
|
||||
void SetFirstChild(LayerD3D9 *aParent);
|
||||
|
||||
virtual Layer* GetLayer() = 0;
|
||||
|
||||
virtual void RenderLayer() = 0;
|
||||
|
||||
IDirect3DDevice9 *device() const { return mD3DManager->device(); }
|
||||
protected:
|
||||
LayerManagerD3D9 *mD3DManager;
|
||||
LayerD3D9 *mNextSibling;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
#endif /* GFX_LAYERMANAGERD3D9_H */
|
435
gfx/layers/d3d9/LayerManagerD3D9Shaders.h
Normal file
435
gfx/layers/d3d9/LayerManagerD3D9Shaders.h
Normal file
@ -0,0 +1,435 @@
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /ELayerQuadVS /nologo
|
||||
// /FhLayerManagerD3D9Shaders.h /VnLayerQuadVS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float4x4 mLayerQuadTransform;
|
||||
// float4x4 mLayerTransform;
|
||||
// float4x4 mProjection;
|
||||
// float4 vRenderTargetOffset;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------------- ----- ----
|
||||
// mLayerQuadTransform c0 4
|
||||
// mLayerTransform c4 4
|
||||
// mProjection c8 4
|
||||
// vRenderTargetOffset c12 1
|
||||
//
|
||||
|
||||
vs_2_0
|
||||
dcl_position v0
|
||||
mul r0, v0.y, c1
|
||||
mad r0, c0, v0.x, r0
|
||||
mad r0, c2, v0.z, r0
|
||||
mad r0, c3, v0.w, r0
|
||||
mul r1, r0.y, c5
|
||||
mad r1, c4, r0.x, r1
|
||||
mad r1, c6, r0.z, r1
|
||||
mad r0, c7, r0.w, r1
|
||||
add r0, r0, -c12
|
||||
mul r1, r0.y, c9
|
||||
mad r1, c8, r0.x, r1
|
||||
mad r1, c10, r0.z, r1
|
||||
mad oPos, c11, r0.w, r1
|
||||
mov oT0.xy, v0
|
||||
|
||||
// approximately 14 instruction slots used
|
||||
#endif
|
||||
|
||||
const BYTE LayerQuadVS[] =
|
||||
{
|
||||
0, 2, 254, 255, 254, 255,
|
||||
67, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 215, 0,
|
||||
0, 0, 0, 2, 254, 255,
|
||||
4, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
208, 0, 0, 0, 108, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
4, 0, 0, 0, 128, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
144, 0, 0, 0, 2, 0,
|
||||
4, 0, 4, 0, 0, 0,
|
||||
128, 0, 0, 0, 0, 0,
|
||||
0, 0, 160, 0, 0, 0,
|
||||
2, 0, 8, 0, 4, 0,
|
||||
0, 0, 128, 0, 0, 0,
|
||||
0, 0, 0, 0, 172, 0,
|
||||
0, 0, 2, 0, 12, 0,
|
||||
1, 0, 0, 0, 192, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
109, 76, 97, 121, 101, 114,
|
||||
81, 117, 97, 100, 84, 114,
|
||||
97, 110, 115, 102, 111, 114,
|
||||
109, 0, 3, 0, 3, 0,
|
||||
4, 0, 4, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
109, 76, 97, 121, 101, 114,
|
||||
84, 114, 97, 110, 115, 102,
|
||||
111, 114, 109, 0, 109, 80,
|
||||
114, 111, 106, 101, 99, 116,
|
||||
105, 111, 110, 0, 118, 82,
|
||||
101, 110, 100, 101, 114, 84,
|
||||
97, 114, 103, 101, 116, 79,
|
||||
102, 102, 115, 101, 116, 0,
|
||||
1, 0, 3, 0, 1, 0,
|
||||
4, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 118, 115,
|
||||
95, 50, 95, 48, 0, 77,
|
||||
105, 99, 114, 111, 115, 111,
|
||||
102, 116, 32, 40, 82, 41,
|
||||
32, 72, 76, 83, 76, 32,
|
||||
83, 104, 97, 100, 101, 114,
|
||||
32, 67, 111, 109, 112, 105,
|
||||
108, 101, 114, 32, 57, 46,
|
||||
50, 55, 46, 57, 53, 50,
|
||||
46, 51, 48, 50, 50, 0,
|
||||
31, 0, 0, 2, 0, 0,
|
||||
0, 128, 0, 0, 15, 144,
|
||||
5, 0, 0, 3, 0, 0,
|
||||
15, 128, 0, 0, 85, 144,
|
||||
1, 0, 228, 160, 4, 0,
|
||||
0, 4, 0, 0, 15, 128,
|
||||
0, 0, 228, 160, 0, 0,
|
||||
0, 144, 0, 0, 228, 128,
|
||||
4, 0, 0, 4, 0, 0,
|
||||
15, 128, 2, 0, 228, 160,
|
||||
0, 0, 170, 144, 0, 0,
|
||||
228, 128, 4, 0, 0, 4,
|
||||
0, 0, 15, 128, 3, 0,
|
||||
228, 160, 0, 0, 255, 144,
|
||||
0, 0, 228, 128, 5, 0,
|
||||
0, 3, 1, 0, 15, 128,
|
||||
0, 0, 85, 128, 5, 0,
|
||||
228, 160, 4, 0, 0, 4,
|
||||
1, 0, 15, 128, 4, 0,
|
||||
228, 160, 0, 0, 0, 128,
|
||||
1, 0, 228, 128, 4, 0,
|
||||
0, 4, 1, 0, 15, 128,
|
||||
6, 0, 228, 160, 0, 0,
|
||||
170, 128, 1, 0, 228, 128,
|
||||
4, 0, 0, 4, 0, 0,
|
||||
15, 128, 7, 0, 228, 160,
|
||||
0, 0, 255, 128, 1, 0,
|
||||
228, 128, 2, 0, 0, 3,
|
||||
0, 0, 15, 128, 0, 0,
|
||||
228, 128, 12, 0, 228, 161,
|
||||
5, 0, 0, 3, 1, 0,
|
||||
15, 128, 0, 0, 85, 128,
|
||||
9, 0, 228, 160, 4, 0,
|
||||
0, 4, 1, 0, 15, 128,
|
||||
8, 0, 228, 160, 0, 0,
|
||||
0, 128, 1, 0, 228, 128,
|
||||
4, 0, 0, 4, 1, 0,
|
||||
15, 128, 10, 0, 228, 160,
|
||||
0, 0, 170, 128, 1, 0,
|
||||
228, 128, 4, 0, 0, 4,
|
||||
0, 0, 15, 192, 11, 0,
|
||||
228, 160, 0, 0, 255, 128,
|
||||
1, 0, 228, 128, 1, 0,
|
||||
0, 2, 0, 0, 3, 224,
|
||||
0, 0, 228, 144, 255, 255,
|
||||
0, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /ERGBShader /nologo /Tps_2_0
|
||||
// /FhLayerManagerD3D9Shaders.h /VnRGBShaderPS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float fLayerOpacity;
|
||||
// sampler2D s2D;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------- ----- ----
|
||||
// fLayerOpacity c0 1
|
||||
// s2D s0 1
|
||||
//
|
||||
|
||||
ps_2_0
|
||||
dcl t0.xy
|
||||
dcl_2d s0
|
||||
texld r0, t0, s0
|
||||
mul r0, r0, c0.x
|
||||
mov oC0, r0
|
||||
|
||||
// approximately 3 instruction slots used (1 texture, 2 arithmetic)
|
||||
#endif
|
||||
|
||||
const BYTE RGBShaderPS[] =
|
||||
{
|
||||
0, 2, 255, 255, 254, 255,
|
||||
45, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 127, 0,
|
||||
0, 0, 0, 2, 255, 255,
|
||||
2, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
120, 0, 0, 0, 68, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 84, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
100, 0, 0, 0, 3, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
104, 0, 0, 0, 0, 0,
|
||||
0, 0, 102, 76, 97, 121,
|
||||
101, 114, 79, 112, 97, 99,
|
||||
105, 116, 121, 0, 171, 171,
|
||||
0, 0, 3, 0, 1, 0,
|
||||
1, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 115, 50,
|
||||
68, 0, 4, 0, 12, 0,
|
||||
1, 0, 1, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
112, 115, 95, 50, 95, 48,
|
||||
0, 77, 105, 99, 114, 111,
|
||||
115, 111, 102, 116, 32, 40,
|
||||
82, 41, 32, 72, 76, 83,
|
||||
76, 32, 83, 104, 97, 100,
|
||||
101, 114, 32, 67, 111, 109,
|
||||
112, 105, 108, 101, 114, 32,
|
||||
57, 46, 50, 55, 46, 57,
|
||||
53, 50, 46, 51, 48, 50,
|
||||
50, 0, 31, 0, 0, 2,
|
||||
0, 0, 0, 128, 0, 0,
|
||||
3, 176, 31, 0, 0, 2,
|
||||
0, 0, 0, 144, 0, 8,
|
||||
15, 160, 66, 0, 0, 3,
|
||||
0, 0, 15, 128, 0, 0,
|
||||
228, 176, 0, 8, 228, 160,
|
||||
5, 0, 0, 3, 0, 0,
|
||||
15, 128, 0, 0, 228, 128,
|
||||
0, 0, 0, 160, 1, 0,
|
||||
0, 2, 0, 8, 15, 128,
|
||||
0, 0, 228, 128, 255, 255,
|
||||
0, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /EYCbCrShader /nologo /Tps_2_0
|
||||
// /FhLayerManagerD3D9Shaders.h /VnYCbCrShaderPS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float fLayerOpacity;
|
||||
// sampler2D s2DCb;
|
||||
// sampler2D s2DCr;
|
||||
// sampler2D s2DY;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------- ----- ----
|
||||
// fLayerOpacity c0 1
|
||||
// s2DY s0 1
|
||||
// s2DCb s1 1
|
||||
// s2DCr s2 1
|
||||
//
|
||||
|
||||
ps_2_0
|
||||
def c1, -0.5, -0.0625, 1.16400003, 1.59599996
|
||||
def c2, 0.813000023, 0.391000003, 2.01799989, 1
|
||||
dcl t0.xy
|
||||
dcl_2d s0
|
||||
dcl_2d s1
|
||||
dcl_2d s2
|
||||
texld r0, t0, s2
|
||||
texld r1, t0, s0
|
||||
texld r2, t0, s1
|
||||
add r0.x, r0.x, c1.x
|
||||
add r0.y, r1.x, c1.y
|
||||
mul r0.y, r0.y, c1.z
|
||||
mad r0.z, r0.x, -c2.x, r0.y
|
||||
mad r1.x, r0.x, c1.w, r0.y
|
||||
add r0.x, r2.x, c1.x
|
||||
mad r1.y, r0.x, -c2.y, r0.z
|
||||
mad r1.z, r0.x, c2.z, r0.y
|
||||
mov r1.w, c2.w
|
||||
mul r0, r1, c0.x
|
||||
mov oC0, r0
|
||||
|
||||
// approximately 14 instruction slots used (3 texture, 11 arithmetic)
|
||||
#endif
|
||||
|
||||
const BYTE YCbCrShaderPS[] =
|
||||
{
|
||||
0, 2, 255, 255, 254, 255,
|
||||
68, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 219, 0,
|
||||
0, 0, 0, 2, 255, 255,
|
||||
4, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
212, 0, 0, 0, 108, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 124, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
140, 0, 0, 0, 3, 0,
|
||||
1, 0, 1, 0, 0, 0,
|
||||
148, 0, 0, 0, 0, 0,
|
||||
0, 0, 164, 0, 0, 0,
|
||||
3, 0, 2, 0, 1, 0,
|
||||
0, 0, 172, 0, 0, 0,
|
||||
0, 0, 0, 0, 188, 0,
|
||||
0, 0, 3, 0, 0, 0,
|
||||
1, 0, 0, 0, 196, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
102, 76, 97, 121, 101, 114,
|
||||
79, 112, 97, 99, 105, 116,
|
||||
121, 0, 171, 171, 0, 0,
|
||||
3, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 115, 50, 68, 67,
|
||||
98, 0, 171, 171, 4, 0,
|
||||
12, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 115, 50, 68, 67,
|
||||
114, 0, 171, 171, 4, 0,
|
||||
12, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 115, 50, 68, 89,
|
||||
0, 171, 171, 171, 4, 0,
|
||||
12, 0, 1, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 0, 112, 115, 95, 50,
|
||||
95, 48, 0, 77, 105, 99,
|
||||
114, 111, 115, 111, 102, 116,
|
||||
32, 40, 82, 41, 32, 72,
|
||||
76, 83, 76, 32, 83, 104,
|
||||
97, 100, 101, 114, 32, 67,
|
||||
111, 109, 112, 105, 108, 101,
|
||||
114, 32, 57, 46, 50, 55,
|
||||
46, 57, 53, 50, 46, 51,
|
||||
48, 50, 50, 0, 81, 0,
|
||||
0, 5, 1, 0, 15, 160,
|
||||
0, 0, 0, 191, 0, 0,
|
||||
128, 189, 244, 253, 148, 63,
|
||||
186, 73, 204, 63, 81, 0,
|
||||
0, 5, 2, 0, 15, 160,
|
||||
197, 32, 80, 63, 39, 49,
|
||||
200, 62, 233, 38, 1, 64,
|
||||
0, 0, 128, 63, 31, 0,
|
||||
0, 2, 0, 0, 0, 128,
|
||||
0, 0, 3, 176, 31, 0,
|
||||
0, 2, 0, 0, 0, 144,
|
||||
0, 8, 15, 160, 31, 0,
|
||||
0, 2, 0, 0, 0, 144,
|
||||
1, 8, 15, 160, 31, 0,
|
||||
0, 2, 0, 0, 0, 144,
|
||||
2, 8, 15, 160, 66, 0,
|
||||
0, 3, 0, 0, 15, 128,
|
||||
0, 0, 228, 176, 2, 8,
|
||||
228, 160, 66, 0, 0, 3,
|
||||
1, 0, 15, 128, 0, 0,
|
||||
228, 176, 0, 8, 228, 160,
|
||||
66, 0, 0, 3, 2, 0,
|
||||
15, 128, 0, 0, 228, 176,
|
||||
1, 8, 228, 160, 2, 0,
|
||||
0, 3, 0, 0, 1, 128,
|
||||
0, 0, 0, 128, 1, 0,
|
||||
0, 160, 2, 0, 0, 3,
|
||||
0, 0, 2, 128, 1, 0,
|
||||
0, 128, 1, 0, 85, 160,
|
||||
5, 0, 0, 3, 0, 0,
|
||||
2, 128, 0, 0, 85, 128,
|
||||
1, 0, 170, 160, 4, 0,
|
||||
0, 4, 0, 0, 4, 128,
|
||||
0, 0, 0, 128, 2, 0,
|
||||
0, 161, 0, 0, 85, 128,
|
||||
4, 0, 0, 4, 1, 0,
|
||||
1, 128, 0, 0, 0, 128,
|
||||
1, 0, 255, 160, 0, 0,
|
||||
85, 128, 2, 0, 0, 3,
|
||||
0, 0, 1, 128, 2, 0,
|
||||
0, 128, 1, 0, 0, 160,
|
||||
4, 0, 0, 4, 1, 0,
|
||||
2, 128, 0, 0, 0, 128,
|
||||
2, 0, 85, 161, 0, 0,
|
||||
170, 128, 4, 0, 0, 4,
|
||||
1, 0, 4, 128, 0, 0,
|
||||
0, 128, 2, 0, 170, 160,
|
||||
0, 0, 85, 128, 1, 0,
|
||||
0, 2, 1, 0, 8, 128,
|
||||
2, 0, 255, 160, 5, 0,
|
||||
0, 3, 0, 0, 15, 128,
|
||||
1, 0, 228, 128, 0, 0,
|
||||
0, 160, 1, 0, 0, 2,
|
||||
0, 8, 15, 128, 0, 0,
|
||||
228, 128, 255, 255, 0, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Generated by Microsoft (R) HLSL Shader Compiler 9.27.952.3022
|
||||
//
|
||||
// fxc LayerManagerD3D9Shaders.hlsl /ESolidColorShader /nologo /Tps_2_0
|
||||
// /FhLayerManagerD3D9Shaders.h /VnSolidColorShaderPS
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// float4 fLayerColor;
|
||||
//
|
||||
//
|
||||
// Registers:
|
||||
//
|
||||
// Name Reg Size
|
||||
// ------------ ----- ----
|
||||
// fLayerColor c0 1
|
||||
//
|
||||
|
||||
ps_2_0
|
||||
mov oC0, c0
|
||||
|
||||
// approximately 1 instruction slot used
|
||||
#endif
|
||||
|
||||
const BYTE SolidColorShaderPS[] =
|
||||
{
|
||||
0, 2, 255, 255, 254, 255,
|
||||
34, 0, 67, 84, 65, 66,
|
||||
28, 0, 0, 0, 83, 0,
|
||||
0, 0, 0, 2, 255, 255,
|
||||
1, 0, 0, 0, 28, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
76, 0, 0, 0, 48, 0,
|
||||
0, 0, 2, 0, 0, 0,
|
||||
1, 0, 0, 0, 60, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
102, 76, 97, 121, 101, 114,
|
||||
67, 111, 108, 111, 114, 0,
|
||||
1, 0, 3, 0, 1, 0,
|
||||
4, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 112, 115,
|
||||
95, 50, 95, 48, 0, 77,
|
||||
105, 99, 114, 111, 115, 111,
|
||||
102, 116, 32, 40, 82, 41,
|
||||
32, 72, 76, 83, 76, 32,
|
||||
83, 104, 97, 100, 101, 114,
|
||||
32, 67, 111, 109, 112, 105,
|
||||
108, 101, 114, 32, 57, 46,
|
||||
50, 55, 46, 57, 53, 50,
|
||||
46, 51, 48, 50, 50, 0,
|
||||
1, 0, 0, 2, 0, 8,
|
||||
15, 128, 0, 0, 228, 160,
|
||||
255, 255, 0, 0
|
||||
};
|
61
gfx/layers/d3d9/LayerManagerD3D9Shaders.hlsl
Normal file
61
gfx/layers/d3d9/LayerManagerD3D9Shaders.hlsl
Normal file
@ -0,0 +1,61 @@
|
||||
float4x4 mLayerQuadTransform;
|
||||
float4x4 mLayerTransform;
|
||||
float4 vRenderTargetOffset;
|
||||
float4x4 mProjection;
|
||||
|
||||
texture tex0;
|
||||
sampler s2D;
|
||||
sampler s2DY;
|
||||
sampler s2DCb;
|
||||
sampler s2DCr;
|
||||
|
||||
float fLayerOpacity;
|
||||
float4 fLayerColor;
|
||||
|
||||
struct VS_INPUT {
|
||||
float4 vPosition : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 vPosition : POSITION;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
};
|
||||
|
||||
VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_OUTPUT outp;
|
||||
outp.vPosition = aVertex.vPosition;
|
||||
outp.vPosition = mul(mLayerQuadTransform, outp.vPosition);
|
||||
outp.vPosition = mul(mLayerTransform, outp.vPosition);
|
||||
outp.vPosition = outp.vPosition - vRenderTargetOffset;
|
||||
outp.vPosition = mul(mProjection, outp.vPosition);
|
||||
outp.vTexCoords = aVertex.vPosition.xy;
|
||||
return outp;
|
||||
}
|
||||
|
||||
float4 RGBShader(const VS_OUTPUT aVertex) : COLOR
|
||||
{
|
||||
return tex2D(s2D, aVertex.vTexCoords) * fLayerOpacity;
|
||||
}
|
||||
|
||||
float4 YCbCrShader(const VS_OUTPUT aVertex) : COLOR
|
||||
{
|
||||
float4 yuv;
|
||||
float4 color;
|
||||
|
||||
yuv.r = tex2D(s2DCr, aVertex.vTexCoords).r - 0.5;
|
||||
yuv.g = tex2D(s2DY, aVertex.vTexCoords).r - 0.0625;
|
||||
yuv.b = tex2D(s2DCb, 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) : COLOR
|
||||
{
|
||||
return fLayerColor;
|
||||
}
|
216
gfx/layers/d3d9/ThebesLayerD3D9.cpp
Normal file
216
gfx/layers/d3d9/ThebesLayerD3D9.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
/* -*- 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 "ThebesLayerD3D9.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ThebesLayerD3D9::ThebesLayerD3D9(LayerManagerD3D9 *aManager)
|
||||
: ThebesLayer(aManager, NULL)
|
||||
, LayerD3D9(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D9*>(this);
|
||||
aManager->mThebesLayers.AppendElement(this);
|
||||
}
|
||||
|
||||
ThebesLayerD3D9::~ThebesLayerD3D9()
|
||||
{
|
||||
mD3DManager->mThebesLayers.RemoveElement(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
if (aRegion.GetBounds() == mVisibleRect) {
|
||||
return;
|
||||
}
|
||||
mVisibleRect = aRegion.GetBounds();
|
||||
|
||||
device()->CreateTexture(mVisibleRect.width, mVisibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
|
||||
mInvalidatedRect = mVisibleRect;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
|
||||
{
|
||||
nsIntRegion invalidatedRegion;
|
||||
invalidatedRegion.Or(aRegion, mInvalidatedRect);
|
||||
invalidatedRegion.And(invalidatedRegion, mVisibleRect);
|
||||
mInvalidatedRect = invalidatedRegion.GetBounds();
|
||||
}
|
||||
|
||||
LayerD3D9::LayerType
|
||||
ThebesLayerD3D9::GetType()
|
||||
{
|
||||
return TYPE_THEBES;
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ThebesLayerD3D9::GetVisibleRect()
|
||||
{
|
||||
return mVisibleRect;
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::RenderLayer()
|
||||
{
|
||||
if (!mTexture) {
|
||||
device()->CreateTexture(mVisibleRect.width, mVisibleRect.height, 1,
|
||||
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
|
||||
mInvalidatedRect = mVisibleRect;
|
||||
}
|
||||
if (!mInvalidatedRect.IsEmpty()) {
|
||||
nsIntRegion region = mInvalidatedRect;
|
||||
|
||||
gfxASurface::gfxImageFormat imageFormat = gfxASurface::ImageFormatARGB32;;
|
||||
nsRefPtr<gfxASurface> destinationSurface;
|
||||
nsRefPtr<gfxContext> context;
|
||||
|
||||
destinationSurface =
|
||||
gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
imageFormat);
|
||||
|
||||
context = new gfxContext(destinationSurface);
|
||||
context->Translate(gfxPoint(-mInvalidatedRect.x, -mInvalidatedRect.y));
|
||||
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
||||
cbInfo.Callback(this, context, region, cbInfo.CallbackData);
|
||||
|
||||
nsRefPtr<IDirect3DTexture9> tmpTexture;
|
||||
device()->CreateTexture(mInvalidatedRect.width, mInvalidatedRect.height, 1,
|
||||
0, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_SYSTEMMEM, getter_AddRefs(tmpTexture), NULL);
|
||||
|
||||
D3DLOCKED_RECT r;
|
||||
tmpTexture->LockRect(0, &r, NULL, 0);
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface =
|
||||
new gfxImageSurface((unsigned char *)r.pBits,
|
||||
gfxIntSize(mInvalidatedRect.width,
|
||||
mInvalidatedRect.height),
|
||||
r.Pitch,
|
||||
imageFormat);
|
||||
|
||||
context = new gfxContext(imgSurface);
|
||||
context->SetSource(destinationSurface);
|
||||
context->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
context->Paint();
|
||||
|
||||
imgSurface = NULL;
|
||||
|
||||
tmpTexture->UnlockRect(0);
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> srcSurface;
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
|
||||
mTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
tmpTexture->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
|
||||
|
||||
POINT point;
|
||||
point.x = mInvalidatedRect.x - mVisibleRect.x;
|
||||
point.y = mInvalidatedRect.y - mVisibleRect.y;
|
||||
device()->UpdateSurface(srcSurface, NULL, dstSurface, &point);
|
||||
}
|
||||
|
||||
float quadTransform[4][4];
|
||||
/*
|
||||
* Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position
|
||||
* and size. To get pixel perfect mapping we offset the quad half a pixel
|
||||
* to the top-left.
|
||||
*
|
||||
* See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx
|
||||
*/
|
||||
memset(&quadTransform, 0, sizeof(quadTransform));
|
||||
quadTransform[0][0] = (float)GetVisibleRect().width;
|
||||
quadTransform[1][1] = (float)GetVisibleRect().height;
|
||||
quadTransform[2][2] = 1.0f;
|
||||
quadTransform[3][0] = (float)GetVisibleRect().x - 0.5f;
|
||||
quadTransform[3][1] = (float)GetVisibleRect().y - 0.5f;
|
||||
quadTransform[3][3] = 1.0f;
|
||||
|
||||
device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4);
|
||||
device()->SetVertexShaderConstantF(4, &mTransform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
/*
|
||||
* We always upload a 4 component float, but the shader will use only the
|
||||
* first component since it's declared as a 'float'.
|
||||
*/
|
||||
opacity[0] = GetOpacity();
|
||||
device()->SetPixelShaderConstantF(0, opacity, 1);
|
||||
|
||||
mD3DManager->SetShaderMode(LayerManagerD3D9::RGBLAYER);
|
||||
|
||||
device()->SetTexture(0, mTexture);
|
||||
device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerD3D9::CleanResources()
|
||||
{
|
||||
mTexture = nsnull;
|
||||
}
|
||||
|
||||
const nsIntRect&
|
||||
ThebesLayerD3D9::GetInvalidatedRect()
|
||||
{
|
||||
return mInvalidatedRect;
|
||||
}
|
||||
|
||||
Layer*
|
||||
ThebesLayerD3D9::GetLayer()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ThebesLayerD3D9::IsEmpty()
|
||||
{
|
||||
return !mTexture;
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
92
gfx/layers/d3d9/ThebesLayerD3D9.h
Normal file
92
gfx/layers/d3d9/ThebesLayerD3D9.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* -*- 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_THEBESLAYERD3D9_H
|
||||
#define GFX_THEBESLAYERD3D9_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D9.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ThebesLayerD3D9 : public ThebesLayer,
|
||||
public LayerD3D9
|
||||
{
|
||||
public:
|
||||
ThebesLayerD3D9(LayerManagerD3D9 *aManager);
|
||||
virtual ~ThebesLayerD3D9();
|
||||
|
||||
/* Layer implementation */
|
||||
void SetVisibleRegion(const nsIntRegion& aRegion);
|
||||
|
||||
/* ThebesLayer implementation */
|
||||
void InvalidateRegion(const nsIntRegion& aRegion);
|
||||
|
||||
/* LayerD3D9 implementation */
|
||||
LayerType GetType();
|
||||
Layer* GetLayer();
|
||||
virtual PRBool IsEmpty();
|
||||
virtual void RenderLayer();
|
||||
virtual void CleanResources();
|
||||
|
||||
/* ThebesLayerD3D9 */
|
||||
const nsIntRect &GetVisibleRect();
|
||||
const nsIntRect &GetInvalidatedRect();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Visible rectangle, this is used to know the size and position of the quad
|
||||
* when doing the rendering of this layer.
|
||||
*/
|
||||
nsIntRect mVisibleRect;
|
||||
/*
|
||||
* Currently invalidated rectangular area.
|
||||
*/
|
||||
nsIntRect mInvalidatedRect;
|
||||
|
||||
/*
|
||||
* D3D9 texture
|
||||
*/
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_THEBESLAYERD3D9_H */
|
Loading…
Reference in New Issue
Block a user