mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1097699 - Part 4: Remove LayerManagerD3D10 code. r=jrmuizel
This commit is contained in:
parent
57039f8c5a
commit
c138f5be1f
@ -35,7 +35,6 @@
|
|||||||
#include "gfxD2DSurface.h"
|
#include "gfxD2DSurface.h"
|
||||||
#include "gfxWindowsPlatform.h"
|
#include "gfxWindowsPlatform.h"
|
||||||
#include <d3d10_1.h>
|
#include <d3d10_1.h>
|
||||||
#include "d3d10/ImageLayerD3D10.h"
|
|
||||||
#include "D3D9SurfaceImage.h"
|
#include "D3D9SurfaceImage.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,241 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "CanvasLayerD3D10.h"
|
|
||||||
|
|
||||||
#include "../d3d9/Nv3DVUtils.h"
|
|
||||||
#include "gfxWindowsSurface.h"
|
|
||||||
#include "gfxWindowsPlatform.h"
|
|
||||||
#include "SharedSurfaceANGLE.h"
|
|
||||||
#include "SharedSurfaceGL.h"
|
|
||||||
#include "gfxContext.h"
|
|
||||||
#include "GLContext.h"
|
|
||||||
#include "gfxPrefs.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
using namespace mozilla::gl;
|
|
||||||
using namespace mozilla::gfx;
|
|
||||||
|
|
||||||
CanvasLayerD3D10::CanvasLayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: CanvasLayer(aManager, nullptr)
|
|
||||||
, LayerD3D10(aManager)
|
|
||||||
, mDataIsPremultiplied(true)
|
|
||||||
, mOriginPos(gl::OriginPos::TopLeft)
|
|
||||||
, mHasAlpha(true)
|
|
||||||
{
|
|
||||||
mImplData = static_cast<LayerD3D10*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
CanvasLayerD3D10::~CanvasLayerD3D10()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CanvasLayerD3D10::Initialize(const Data& aData)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
|
|
||||||
|
|
||||||
if (aData.mGLContext) {
|
|
||||||
mGLContext = aData.mGLContext;
|
|
||||||
NS_ASSERTION(mGLContext->IsOffscreen(), "Canvas GLContext must be offscreen.");
|
|
||||||
mDataIsPremultiplied = aData.mIsGLAlphaPremult;
|
|
||||||
mOriginPos = gl::OriginPos::TopLeft;
|
|
||||||
|
|
||||||
GLScreenBuffer* screen = mGLContext->Screen();
|
|
||||||
|
|
||||||
UniquePtr<SurfaceFactory> factory = nullptr;
|
|
||||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
|
||||||
if (mGLContext->IsANGLE()) {
|
|
||||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext,
|
|
||||||
screen->mCaps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (factory) {
|
|
||||||
screen->Morph(Move(factory));
|
|
||||||
}
|
|
||||||
} else if (aData.mDrawTarget) {
|
|
||||||
mDrawTarget = aData.mDrawTarget;
|
|
||||||
void *texture = mDrawTarget->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE);
|
|
||||||
|
|
||||||
if (texture) {
|
|
||||||
mTexture = static_cast<ID3D10Texture2D*>(texture);
|
|
||||||
|
|
||||||
NS_ASSERTION(!aData.mGLContext,
|
|
||||||
"CanvasLayer can't have both DrawTarget and WebGLContext/Surface");
|
|
||||||
|
|
||||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
|
||||||
device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRView));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX we should store mDrawTarget and use it directly in UpdateSurface,
|
|
||||||
// bypassing Thebes
|
|
||||||
mSurface = mDrawTarget->Snapshot();
|
|
||||||
} else {
|
|
||||||
MOZ_CRASH("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
|
|
||||||
}
|
|
||||||
|
|
||||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
|
||||||
mIsD2DTexture = false;
|
|
||||||
|
|
||||||
// Create a texture in case we need to readback.
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mBounds.width, mBounds.height, 1, 1);
|
|
||||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
|
||||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
|
||||||
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(mTexture));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create texture for CanvasLayer!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mUploadSRView));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CanvasLayerD3D10::UpdateSurface()
|
|
||||||
{
|
|
||||||
if (!IsDirty())
|
|
||||||
return;
|
|
||||||
Painted();
|
|
||||||
|
|
||||||
if (mDrawTarget) {
|
|
||||||
mDrawTarget->Flush();
|
|
||||||
} else if (mIsD2DTexture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mTexture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedSurface* surf = nullptr;
|
|
||||||
if (mGLContext) {
|
|
||||||
auto screen = mGLContext->Screen();
|
|
||||||
MOZ_ASSERT(screen);
|
|
||||||
|
|
||||||
surf = screen->Front()->Surf();
|
|
||||||
if (!surf)
|
|
||||||
return;
|
|
||||||
surf->WaitSync();
|
|
||||||
|
|
||||||
if (surf->mType == SharedSurfaceType::EGLSurfaceANGLE) {
|
|
||||||
SharedSurface_ANGLEShareHandle* shareSurf = SharedSurface_ANGLEShareHandle::Cast(surf);
|
|
||||||
HANDLE shareHandle = shareSurf->GetShareHandle();
|
|
||||||
|
|
||||||
HRESULT hr = device()->OpenSharedResource(shareHandle,
|
|
||||||
__uuidof(ID3D10Texture2D),
|
|
||||||
getter_AddRefs(mTexture));
|
|
||||||
if (FAILED(hr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
hr = device()->CreateShaderResourceView(mTexture,
|
|
||||||
nullptr,
|
|
||||||
getter_AddRefs(mSRView));
|
|
||||||
if (FAILED(hr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D10_MAPPED_TEXTURE2D map;
|
|
||||||
HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
gfxWarning() << "Failed to lock CanvasLayer texture.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<DrawTarget> destTarget =
|
|
||||||
Factory::CreateDrawTargetForD3D10Texture(mTexture,
|
|
||||||
SurfaceFormat::R8G8B8A8);
|
|
||||||
|
|
||||||
if (!destTarget) {
|
|
||||||
gfxWarning() << "Invalid D3D10 texture target R8G8B8A8";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surf) {
|
|
||||||
if (!ReadbackSharedSurface(surf, destTarget)) {
|
|
||||||
gfxWarning() << "Failed to readback into texture.";
|
|
||||||
}
|
|
||||||
} else if (mSurface) {
|
|
||||||
Rect r(Point(0, 0), ToRect(mBounds).Size());
|
|
||||||
destTarget->DrawSurface(mSurface, r, r, DrawSurfaceOptions(),
|
|
||||||
DrawOptions(1.0F, CompositionOp::OP_SOURCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
mTexture->Unmap(0);
|
|
||||||
mSRView = mUploadSRView;
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer*
|
|
||||||
CanvasLayerD3D10::GetLayer()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CanvasLayerD3D10::RenderLayer()
|
|
||||||
{
|
|
||||||
FirePreTransactionCallback();
|
|
||||||
UpdateSurface();
|
|
||||||
FireDidTransactionCallback();
|
|
||||||
|
|
||||||
if (!mTexture)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
|
||||||
|
|
||||||
SetEffectTransformAndOpacity();
|
|
||||||
|
|
||||||
uint8_t shaderFlags = 0;
|
|
||||||
shaderFlags |= LoadMaskTexture();
|
|
||||||
shaderFlags |= mDataIsPremultiplied
|
|
||||||
? SHADER_PREMUL : SHADER_NON_PREMUL | SHADER_RGBA;
|
|
||||||
shaderFlags |= mHasAlpha ? SHADER_RGBA : SHADER_RGB;
|
|
||||||
shaderFlags |= mFilter == GraphicsFilter::FILTER_NEAREST
|
|
||||||
? SHADER_POINT : SHADER_LINEAR;
|
|
||||||
ID3D10EffectTechnique* technique = SelectShader(shaderFlags);
|
|
||||||
|
|
||||||
if (mSRView) {
|
|
||||||
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
|
|
||||||
}
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)mBounds.x,
|
|
||||||
(float)mBounds.y,
|
|
||||||
(float)mBounds.width,
|
|
||||||
(float)mBounds.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
|
|
||||||
|
|
||||||
if (needsYFlip) {
|
|
||||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
0,
|
|
||||||
1.0f,
|
|
||||||
1.0f,
|
|
||||||
-1.0f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
|
|
||||||
if (needsYFlip) {
|
|
||||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->
|
|
||||||
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace layers */
|
|
||||||
} /* namespace mozilla */
|
|
@ -1,73 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_CANVASLAYERD3D10_H
|
|
||||||
#define GFX_CANVASLAYERD3D10_H
|
|
||||||
|
|
||||||
#include "GLContextTypes.h"
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
|
|
||||||
namespace gl {
|
|
||||||
class GLContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class CanvasLayerD3D10 : public CanvasLayer,
|
|
||||||
public LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CanvasLayerD3D10(LayerManagerD3D10 *aManager);
|
|
||||||
~CanvasLayerD3D10();
|
|
||||||
|
|
||||||
// CanvasLayer implementation
|
|
||||||
virtual void Initialize(const Data& aData);
|
|
||||||
|
|
||||||
// LayerD3D10 implementation
|
|
||||||
virtual Layer* GetLayer();
|
|
||||||
virtual void RenderLayer();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef mozilla::gl::GLContext GLContext;
|
|
||||||
|
|
||||||
void UpdateSurface();
|
|
||||||
|
|
||||||
RefPtr<gfx::SourceSurface> mSurface;
|
|
||||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
|
||||||
nsRefPtr<GLContext> mGLContext;
|
|
||||||
nsRefPtr<ID3D10Texture2D> mTexture;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mUploadSRView;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mSRView;
|
|
||||||
|
|
||||||
bool mDataIsPremultiplied;
|
|
||||||
gl::OriginPos mOriginPos;
|
|
||||||
bool mIsD2DTexture;
|
|
||||||
bool mHasAlpha;
|
|
||||||
|
|
||||||
nsAutoArrayPtr<uint8_t> mCachedTempBlob;
|
|
||||||
uint32_t mCachedTempBlob_Size;
|
|
||||||
|
|
||||||
uint8_t* GetTempBlob(const uint32_t aSize)
|
|
||||||
{
|
|
||||||
if (!mCachedTempBlob || aSize != mCachedTempBlob_Size) {
|
|
||||||
mCachedTempBlob = new uint8_t[aSize];
|
|
||||||
mCachedTempBlob_Size = aSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mCachedTempBlob;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiscardTempBlob()
|
|
||||||
{
|
|
||||||
mCachedTempBlob = nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
#endif /* GFX_CANVASLAYERD3D10_H */
|
|
@ -1,60 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "ColorLayerD3D10.h"
|
|
||||||
|
|
||||||
#include "../d3d9/Nv3DVUtils.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
ColorLayerD3D10::ColorLayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: ColorLayer(aManager, nullptr)
|
|
||||||
, LayerD3D10(aManager)
|
|
||||||
{
|
|
||||||
mImplData = static_cast<LayerD3D10*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer*
|
|
||||||
ColorLayerD3D10::GetLayer()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ColorLayerD3D10::RenderLayer()
|
|
||||||
{
|
|
||||||
float color[4];
|
|
||||||
// output color is premultiplied, so we need to adjust all channels.
|
|
||||||
// mColor is not premultiplied.
|
|
||||||
float opacity = GetEffectiveOpacity() * mColor.a;
|
|
||||||
color[0] = (float)(mColor.r * opacity);
|
|
||||||
color[1] = (float)(mColor.g * opacity);
|
|
||||||
color[2] = (float)(mColor.b * opacity);
|
|
||||||
color[3] = opacity;
|
|
||||||
|
|
||||||
const gfx::Matrix4x4& transform = GetEffectiveTransform();
|
|
||||||
void* raw = &const_cast<gfx::Matrix4x4&>(transform)._11;
|
|
||||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
|
|
||||||
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
|
|
||||||
|
|
||||||
ID3D10EffectTechnique *technique = SelectShader(SHADER_SOLID | LoadMaskTexture());
|
|
||||||
|
|
||||||
nsIntRect bounds = GetBounds();
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)bounds.x,
|
|
||||||
(float)bounds.y,
|
|
||||||
(float)bounds.width,
|
|
||||||
(float)bounds.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
@ -1,27 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_COLORLAYERD3D10_H
|
|
||||||
#define GFX_COLORLAYERD3D10_H
|
|
||||||
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class ColorLayerD3D10 : public ColorLayer,
|
|
||||||
public LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ColorLayerD3D10(LayerManagerD3D10 *aManager);
|
|
||||||
|
|
||||||
/* LayerD3D10 implementation */
|
|
||||||
virtual Layer* GetLayer();
|
|
||||||
virtual void RenderLayer();
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
#endif /* GFX_PAINTEDLAYERD3D10_H */
|
|
@ -1,268 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "ContainerLayerD3D10.h"
|
|
||||||
|
|
||||||
#include "PaintedLayerD3D10.h"
|
|
||||||
#include "ReadbackProcessor.h"
|
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
ContainerLayerD3D10::ContainerLayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: ContainerLayer(aManager, nullptr)
|
|
||||||
, LayerD3D10(aManager)
|
|
||||||
{
|
|
||||||
mImplData = static_cast<LayerD3D10*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ContainerLayerD3D10::~ContainerLayerD3D10()
|
|
||||||
{
|
|
||||||
while (mFirstChild) {
|
|
||||||
RemoveChild(mFirstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer*
|
|
||||||
ContainerLayerD3D10::GetLayer()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerD3D10*
|
|
||||||
ContainerLayerD3D10::GetFirstChildD3D10()
|
|
||||||
{
|
|
||||||
if (!mFirstChild) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return static_cast<LayerD3D10*>(mFirstChild->ImplData());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ContainerLayerD3D10::RenderLayer()
|
|
||||||
{
|
|
||||||
float renderTargetOffset[] = { 0, 0 };
|
|
||||||
|
|
||||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
|
||||||
float opacity = GetEffectiveOpacity();
|
|
||||||
bool useIntermediate = UseIntermediateSurface();
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10RenderTargetView> previousRTView;
|
|
||||||
nsRefPtr<ID3D10Texture2D> renderTexture;
|
|
||||||
nsRefPtr<ID3D10RenderTargetView> rtView;
|
|
||||||
float previousRenderTargetOffset[2];
|
|
||||||
nsIntSize previousViewportSize;
|
|
||||||
|
|
||||||
gfx3DMatrix oldViewMatrix;
|
|
||||||
|
|
||||||
if (useIntermediate) {
|
|
||||||
device()->OMGetRenderTargets(1, getter_AddRefs(previousRTView), nullptr);
|
|
||||||
|
|
||||||
D3D10_TEXTURE2D_DESC desc;
|
|
||||||
memset(&desc, 0, sizeof(D3D10_TEXTURE2D_DESC));
|
|
||||||
desc.ArraySize = 1;
|
|
||||||
desc.MipLevels = 1;
|
|
||||||
desc.Width = visibleRect.width;
|
|
||||||
desc.Height = visibleRect.height;
|
|
||||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
|
||||||
desc.SampleDesc.Count = 1;
|
|
||||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
HRESULT hr;
|
|
||||||
hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(renderTexture));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create new texture for ContainerLayerD3D10!"),
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = device()->CreateRenderTargetView(renderTexture, nullptr, getter_AddRefs(rtView));
|
|
||||||
NS_ASSERTION(SUCCEEDED(hr), "Failed to create render target view for ContainerLayerD3D10!");
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vRenderTargetOffset")->
|
|
||||||
GetRawValue(previousRenderTargetOffset, 0, 8);
|
|
||||||
|
|
||||||
previousViewportSize = mD3DManager->GetViewport();
|
|
||||||
|
|
||||||
if (mVisibleRegion.GetNumRects() != 1 || !(GetContentFlags() & CONTENT_OPAQUE)) {
|
|
||||||
Matrix4x4 transform3D = GetEffectiveTransform();
|
|
||||||
Matrix transform;
|
|
||||||
// If we have an opaque ancestor layer, then we can be sure that
|
|
||||||
// all the pixels we draw into are either opaque already or will be
|
|
||||||
// covered by something opaque. Otherwise copying up the background is
|
|
||||||
// not safe.
|
|
||||||
if (mSupportsComponentAlphaChildren) {
|
|
||||||
bool is2d = transform3D.Is2D(&transform);
|
|
||||||
NS_ASSERTION(is2d, "Transform should be 2d when mSupportsComponentAlphaChildren.");
|
|
||||||
|
|
||||||
// Copy background up from below. This applies any 2D transform that is
|
|
||||||
// applied to use relative to our parent, and compensates for the offset
|
|
||||||
// that was applied on our parent's rendering.
|
|
||||||
D3D10_BOX srcBox;
|
|
||||||
srcBox.left = std::max<int32_t>(visibleRect.x + int32_t(transform._31) - int32_t(previousRenderTargetOffset[0]), 0);
|
|
||||||
srcBox.top = std::max<int32_t>(visibleRect.y + int32_t(transform._32) - int32_t(previousRenderTargetOffset[1]), 0);
|
|
||||||
srcBox.right = std::min<int32_t>(srcBox.left + visibleRect.width, previousViewportSize.width);
|
|
||||||
srcBox.bottom = std::min<int32_t>(srcBox.top + visibleRect.height, previousViewportSize.height);
|
|
||||||
srcBox.back = 1;
|
|
||||||
srcBox.front = 0;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Resource> srcResource;
|
|
||||||
previousRTView->GetResource(getter_AddRefs(srcResource));
|
|
||||||
|
|
||||||
device()->CopySubresourceRegion(renderTexture, 0,
|
|
||||||
0, 0, 0,
|
|
||||||
srcResource, 0,
|
|
||||||
&srcBox);
|
|
||||||
} else {
|
|
||||||
float black[] = { 0, 0, 0, 0};
|
|
||||||
device()->ClearRenderTargetView(rtView, black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D10RenderTargetView *rtViewPtr = rtView;
|
|
||||||
device()->OMSetRenderTargets(1, &rtViewPtr, nullptr);
|
|
||||||
|
|
||||||
renderTargetOffset[0] = (float)visibleRect.x;
|
|
||||||
renderTargetOffset[1] = (float)visibleRect.y;
|
|
||||||
effect()->GetVariableByName("vRenderTargetOffset")->
|
|
||||||
SetRawValue(renderTargetOffset, 0, 8);
|
|
||||||
|
|
||||||
mD3DManager->SetViewport(nsIntSize(visibleRect.Size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D10_RECT oldD3D10Scissor;
|
|
||||||
UINT numRects = 1;
|
|
||||||
device()->RSGetScissorRects(&numRects, &oldD3D10Scissor);
|
|
||||||
// Convert scissor to an nsIntRect. D3D10_RECT's are exclusive
|
|
||||||
// on the bottom and right values.
|
|
||||||
nsIntRect oldScissor(oldD3D10Scissor.left,
|
|
||||||
oldD3D10Scissor.top,
|
|
||||||
oldD3D10Scissor.right - oldD3D10Scissor.left,
|
|
||||||
oldD3D10Scissor.bottom - oldD3D10Scissor.top);
|
|
||||||
|
|
||||||
nsAutoTArray<Layer*, 12> children;
|
|
||||||
SortChildrenBy3DZOrder(children);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Render this container's contents.
|
|
||||||
*/
|
|
||||||
for (uint32_t i = 0; i < children.Length(); i++) {
|
|
||||||
LayerD3D10* layerToRender = static_cast<LayerD3D10*>(children.ElementAt(i)->ImplData());
|
|
||||||
|
|
||||||
if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIntRect scissorRect =
|
|
||||||
RenderTargetPixel::ToUntyped(layerToRender->GetLayer()->CalculateScissorRect(RenderTargetPixel::FromUntyped(oldScissor)));
|
|
||||||
if (scissorRect.IsEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D10_RECT d3drect;
|
|
||||||
d3drect.left = scissorRect.x;
|
|
||||||
d3drect.top = scissorRect.y;
|
|
||||||
d3drect.right = scissorRect.x + scissorRect.width;
|
|
||||||
d3drect.bottom = scissorRect.y + scissorRect.height;
|
|
||||||
device()->RSSetScissorRects(1, &d3drect);
|
|
||||||
|
|
||||||
layerToRender->RenderLayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
device()->RSSetScissorRects(1, &oldD3D10Scissor);
|
|
||||||
|
|
||||||
if (useIntermediate) {
|
|
||||||
mD3DManager->SetViewport(previousViewportSize);
|
|
||||||
ID3D10RenderTargetView *rtView = previousRTView;
|
|
||||||
device()->OMSetRenderTargets(1, &rtView, nullptr);
|
|
||||||
effect()->GetVariableByName("vRenderTargetOffset")->
|
|
||||||
SetRawValue(previousRenderTargetOffset, 0, 8);
|
|
||||||
|
|
||||||
SetEffectTransformAndOpacity();
|
|
||||||
|
|
||||||
ID3D10EffectTechnique *technique;
|
|
||||||
if (LoadMaskTexture()) {
|
|
||||||
if (GetTransform().CanDraw2D()) {
|
|
||||||
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_MASK);
|
|
||||||
} else {
|
|
||||||
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_MASK_3D);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_NO_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)visibleRect.x,
|
|
||||||
(float)visibleRect.y,
|
|
||||||
(float)visibleRect.width,
|
|
||||||
(float)visibleRect.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
|
|
||||||
ID3D10ShaderResourceView *view;
|
|
||||||
device()->CreateShaderResourceView(renderTexture, nullptr, &view);
|
|
||||||
device()->PSSetShaderResources(0, 1, &view);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
view->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ContainerLayerD3D10::LayerManagerDestroyed()
|
|
||||||
{
|
|
||||||
while (mFirstChild) {
|
|
||||||
GetFirstChildD3D10()->LayerManagerDestroyed();
|
|
||||||
RemoveChild(mFirstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ContainerLayerD3D10::Validate()
|
|
||||||
{
|
|
||||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
|
||||||
|
|
||||||
mSupportsComponentAlphaChildren = false;
|
|
||||||
|
|
||||||
if (UseIntermediateSurface()) {
|
|
||||||
Matrix4x4 transform3D = GetEffectiveTransform();
|
|
||||||
Matrix transform;
|
|
||||||
|
|
||||||
if (mVisibleRegion.GetNumRects() == 1 && (GetContentFlags() & CONTENT_OPAQUE)) {
|
|
||||||
// don't need a background, we're going to paint all opaque stuff
|
|
||||||
mSupportsComponentAlphaChildren = true;
|
|
||||||
} else {
|
|
||||||
if (HasOpaqueAncestorLayer(this) &&
|
|
||||||
transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation() &&
|
|
||||||
GetParent()->GetEffectiveVisibleRegion().GetBounds().Contains(visibleRect))
|
|
||||||
{
|
|
||||||
// In this case we can copy up the background. See RenderLayer.
|
|
||||||
mSupportsComponentAlphaChildren = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mSupportsComponentAlphaChildren = (GetContentFlags() & CONTENT_OPAQUE) ||
|
|
||||||
(mParent && mParent->SupportsComponentAlphaChildren());
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadbackProcessor readback;
|
|
||||||
readback.BuildUpdates(this);
|
|
||||||
|
|
||||||
Layer *layer = GetFirstChild();
|
|
||||||
while (layer) {
|
|
||||||
if (layer->GetType() == TYPE_PAINTED) {
|
|
||||||
static_cast<PaintedLayerD3D10*>(layer)->Validate(&readback);
|
|
||||||
} else {
|
|
||||||
static_cast<LayerD3D10*>(layer->ImplData())->Validate();
|
|
||||||
}
|
|
||||||
layer = layer->GetNextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
@ -1,42 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_CONTAINERLAYERD3D10_H
|
|
||||||
#define GFX_CONTAINERLAYERD3D10_H
|
|
||||||
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class ContainerLayerD3D10 : public ContainerLayer,
|
|
||||||
public LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ContainerLayerD3D10(LayerManagerD3D10 *aManager);
|
|
||||||
~ContainerLayerD3D10();
|
|
||||||
|
|
||||||
nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); }
|
|
||||||
|
|
||||||
/* LayerD3D10 implementation */
|
|
||||||
virtual Layer* GetLayer();
|
|
||||||
|
|
||||||
virtual LayerD3D10* GetFirstChildD3D10();
|
|
||||||
|
|
||||||
virtual void RenderLayer();
|
|
||||||
virtual void Validate();
|
|
||||||
|
|
||||||
virtual void LayerManagerDestroyed();
|
|
||||||
|
|
||||||
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
|
|
||||||
{
|
|
||||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
|
|
||||||
#endif /* GFX_CONTAINERLAYERD3D10_H */
|
|
@ -1,400 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "ImageLayerD3D10.h"
|
|
||||||
#include "gfxD2DSurface.h"
|
|
||||||
#include "gfxWindowsSurface.h"
|
|
||||||
#include "yuv_convert.h"
|
|
||||||
#include "../d3d9/Nv3DVUtils.h"
|
|
||||||
#include "D3D9SurfaceImage.h"
|
|
||||||
#include "mozilla/gfx/Point.h"
|
|
||||||
#include "gfx2DGlue.h"
|
|
||||||
|
|
||||||
#include "gfxWindowsPlatform.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
|
||||||
|
|
||||||
static already_AddRefed<ID3D10Texture2D>
|
|
||||||
DataToTexture(ID3D10Device *aDevice,
|
|
||||||
unsigned char *data,
|
|
||||||
int stride,
|
|
||||||
const IntSize &aSize)
|
|
||||||
{
|
|
||||||
D3D10_SUBRESOURCE_DATA srdata;
|
|
||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
|
||||||
aSize.width,
|
|
||||||
aSize.height,
|
|
||||||
1, 1);
|
|
||||||
desc.Usage = D3D10_USAGE_IMMUTABLE;
|
|
||||||
|
|
||||||
srdata.pSysMem = data;
|
|
||||||
srdata.SysMemPitch = stride;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Texture2D> texture;
|
|
||||||
HRESULT hr = aDevice->CreateTexture2D(&desc, &srdata, getter_AddRefs(texture));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create texture for data"),
|
|
||||||
hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
static already_AddRefed<ID3D10Texture2D>
|
|
||||||
SurfaceToTexture(ID3D10Device *aDevice,
|
|
||||||
SourceSurface *aSurface,
|
|
||||||
const IntSize &aSize)
|
|
||||||
{
|
|
||||||
if (!aSurface) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *nativeSurf =
|
|
||||||
aSurface->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE);
|
|
||||||
if (nativeSurf) {
|
|
||||||
nsRefPtr<ID3D10Texture2D> texture =
|
|
||||||
static_cast<ID3D10Texture2D*>(nativeSurf);
|
|
||||||
ID3D10Device *dev;
|
|
||||||
texture->GetDevice(&dev);
|
|
||||||
if (dev == aDevice) {
|
|
||||||
return texture.forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
|
|
||||||
if (!dataSurface) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
DataSourceSurface::MappedSurface map;
|
|
||||||
if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
nsRefPtr<ID3D10Texture2D> texture =
|
|
||||||
DataToTexture(aDevice, map.mData, map.mStride, aSize);
|
|
||||||
dataSurface->Unmap();
|
|
||||||
return texture.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer*
|
|
||||||
ImageLayerD3D10::GetLayer()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a shader resource view for an image.
|
|
||||||
* Returns nullptr if unsuccessful.
|
|
||||||
* If successful, aHasAlpha will be true iff the resulting texture
|
|
||||||
* has an alpha component.
|
|
||||||
*/
|
|
||||||
ID3D10ShaderResourceView*
|
|
||||||
ImageLayerD3D10::GetImageSRView(Image* aImage, bool& aHasAlpha, IDXGIKeyedMutex **aMutex)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aImage, "Null image.");
|
|
||||||
|
|
||||||
if (aImage->GetFormat() == ImageFormat::CAIRO_SURFACE) {
|
|
||||||
CairoImage *cairoImage =
|
|
||||||
static_cast<CairoImage*>(aImage);
|
|
||||||
|
|
||||||
RefPtr<SourceSurface> surf = cairoImage->GetAsSourceSurface();
|
|
||||||
if (!surf) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
|
|
||||||
nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData());
|
|
||||||
dat->mTexture = SurfaceToTexture(device(), surf, cairoImage->GetSize());
|
|
||||||
|
|
||||||
if (dat->mTexture) {
|
|
||||||
device()->CreateShaderResourceView(dat->mTexture, nullptr, getter_AddRefs(dat->mSRView));
|
|
||||||
aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, dat.forget());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aHasAlpha = surf->GetFormat() == SurfaceFormat::B8G8R8A8;
|
|
||||||
} else if (aImage->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) {
|
|
||||||
if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
|
|
||||||
// Use resource sharing to open the D3D9 texture as a D3D10 texture,
|
|
||||||
HRESULT hr;
|
|
||||||
D3D9SurfaceImage* d3dImage = reinterpret_cast<D3D9SurfaceImage*>(aImage);
|
|
||||||
nsRefPtr<ID3D10Texture2D> texture;
|
|
||||||
hr = device()->OpenSharedResource(d3dImage->GetShareHandle(),
|
|
||||||
IID_ID3D10Texture2D,
|
|
||||||
(void**)getter_AddRefs(texture));
|
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
|
|
||||||
|
|
||||||
nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData());
|
|
||||||
dat->mTexture = texture;
|
|
||||||
|
|
||||||
hr = device()->CreateShaderResourceView(dat->mTexture, nullptr, getter_AddRefs(dat->mSRView));
|
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && dat->mSRView, nullptr);
|
|
||||||
|
|
||||||
aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, dat.forget());
|
|
||||||
}
|
|
||||||
aHasAlpha = false;
|
|
||||||
} else {
|
|
||||||
NS_WARNING("Incorrect image type.");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureD3D10BackendData *data =
|
|
||||||
static_cast<TextureD3D10BackendData*>(aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10));
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aMutex &&
|
|
||||||
SUCCEEDED(data->mTexture->QueryInterface(IID_IDXGIKeyedMutex, (void**)aMutex))) {
|
|
||||||
if (FAILED((*aMutex)->AcquireSync(0, 0))) {
|
|
||||||
NS_WARNING("Failed to acquire sync on keyed mutex, plugin forgot to release?");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Device> dev;
|
|
||||||
data->mTexture->GetDevice(getter_AddRefs(dev));
|
|
||||||
if (dev != device()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data->mSRView;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ImageLayerD3D10::RenderLayer()
|
|
||||||
{
|
|
||||||
ImageContainer *container = GetContainer();
|
|
||||||
if (!container) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoLockImage autoLock(container);
|
|
||||||
|
|
||||||
Image *image = autoLock.GetImage();
|
|
||||||
if (!image) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntSize size = image->GetSize();
|
|
||||||
|
|
||||||
SetEffectTransformAndOpacity();
|
|
||||||
|
|
||||||
ID3D10EffectTechnique *technique;
|
|
||||||
nsRefPtr<IDXGIKeyedMutex> keyedMutex;
|
|
||||||
|
|
||||||
if (image->GetFormat() == ImageFormat::CAIRO_SURFACE ||
|
|
||||||
image->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) {
|
|
||||||
NS_ASSERTION(image->GetFormat() != ImageFormat::CAIRO_SURFACE ||
|
|
||||||
!static_cast<CairoImage*>(image)->mSourceSurface ||
|
|
||||||
static_cast<CairoImage*>(image)->mSourceSurface->GetFormat() != SurfaceFormat::A8,
|
|
||||||
"Image layer has alpha image");
|
|
||||||
bool hasAlpha = false;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> srView = GetImageSRView(image, hasAlpha, getter_AddRefs(keyedMutex));
|
|
||||||
if (!srView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t shaderFlags = SHADER_PREMUL;
|
|
||||||
shaderFlags |= LoadMaskTexture();
|
|
||||||
shaderFlags |= hasAlpha
|
|
||||||
? SHADER_RGBA : SHADER_RGB;
|
|
||||||
shaderFlags |= mFilter == GraphicsFilter::FILTER_NEAREST
|
|
||||||
? SHADER_POINT : SHADER_LINEAR;
|
|
||||||
technique = SelectShader(shaderFlags);
|
|
||||||
|
|
||||||
|
|
||||||
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(srView);
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)0,
|
|
||||||
(float)0,
|
|
||||||
(float)size.width,
|
|
||||||
(float)size.height)
|
|
||||||
);
|
|
||||||
} else if (image->GetFormat() == ImageFormat::PLANAR_YCBCR) {
|
|
||||||
PlanarYCbCrImage *yuvImage =
|
|
||||||
static_cast<PlanarYCbCrImage*>(image);
|
|
||||||
|
|
||||||
if (!yuvImage->IsValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!yuvImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
|
|
||||||
AllocateTexturesYCbCr(yuvImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlanarYCbCrD3D10BackendData *data =
|
|
||||||
static_cast<PlanarYCbCrD3D10BackendData*>(yuvImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10));
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Device> dev;
|
|
||||||
data->mYTexture->GetDevice(getter_AddRefs(dev));
|
|
||||||
if (dev != device()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: At some point we should try to deal with mFilter here, you don't
|
|
||||||
// really want to use point filtering in the case of NEAREST, since that
|
|
||||||
// would also use point filtering for Chroma upsampling. Where most likely
|
|
||||||
// the user would only want point filtering for final RGB image upsampling.
|
|
||||||
|
|
||||||
technique = SelectShader(SHADER_YCBCR | LoadMaskTexture());
|
|
||||||
|
|
||||||
effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(data->mYView);
|
|
||||||
effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(data->mCbView);
|
|
||||||
effect()->GetVariableByName("tCr")->AsShaderResource()->SetResource(data->mCrView);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Send 3d control data and metadata to NV3DVUtils
|
|
||||||
*/
|
|
||||||
if (GetNv3DVUtils()) {
|
|
||||||
Nv_Stereo_Mode mode;
|
|
||||||
switch (yuvImage->GetData()->mStereoMode) {
|
|
||||||
case StereoMode::LEFT_RIGHT:
|
|
||||||
mode = NV_STEREO_MODE_LEFT_RIGHT;
|
|
||||||
break;
|
|
||||||
case StereoMode::RIGHT_LEFT:
|
|
||||||
mode = NV_STEREO_MODE_RIGHT_LEFT;
|
|
||||||
break;
|
|
||||||
case StereoMode::BOTTOM_TOP:
|
|
||||||
mode = NV_STEREO_MODE_BOTTOM_TOP;
|
|
||||||
break;
|
|
||||||
case StereoMode::TOP_BOTTOM:
|
|
||||||
mode = NV_STEREO_MODE_TOP_BOTTOM;
|
|
||||||
break;
|
|
||||||
case StereoMode::MONO:
|
|
||||||
mode = NV_STEREO_MODE_MONO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send control data even in mono case so driver knows to leave stereo mode.
|
|
||||||
GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
|
|
||||||
|
|
||||||
if (yuvImage->GetData()->mStereoMode != StereoMode::MONO) {
|
|
||||||
// Dst resource is optional
|
|
||||||
GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->GetData()->mYSize.width,
|
|
||||||
(unsigned int)yuvImage->GetData()->mYSize.height, (HANDLE)(data->mYTexture), (HANDLE)(nullptr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)0,
|
|
||||||
(float)0,
|
|
||||||
(float)size.width,
|
|
||||||
(float)size.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)yuvImage->GetData()->mPicX / yuvImage->GetData()->mYSize.width,
|
|
||||||
(float)yuvImage->GetData()->mPicY / yuvImage->GetData()->mYSize.height,
|
|
||||||
(float)yuvImage->GetData()->mPicSize.width / yuvImage->GetData()->mYSize.width,
|
|
||||||
(float)yuvImage->GetData()->mPicSize.height / yuvImage->GetData()->mYSize.height)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
MOZ_CRASH("unexpected image format");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool resetTexCoords = image->GetFormat() == ImageFormat::PLANAR_YCBCR;
|
|
||||||
image = nullptr;
|
|
||||||
autoLock.Unlock();
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
|
|
||||||
if (keyedMutex) {
|
|
||||||
keyedMutex->ReleaseSync(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resetTexCoords) {
|
|
||||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->
|
|
||||||
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
GetContainer()->NotifyPaintedImage(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageLayerD3D10::AllocateTexturesYCbCr(PlanarYCbCrImage *aImage)
|
|
||||||
{
|
|
||||||
nsAutoPtr<PlanarYCbCrD3D10BackendData> backendData(
|
|
||||||
new PlanarYCbCrD3D10BackendData);
|
|
||||||
|
|
||||||
const PlanarYCbCrData *data = aImage->GetData();
|
|
||||||
|
|
||||||
D3D10_SUBRESOURCE_DATA dataY;
|
|
||||||
D3D10_SUBRESOURCE_DATA dataCb;
|
|
||||||
D3D10_SUBRESOURCE_DATA dataCr;
|
|
||||||
CD3D10_TEXTURE2D_DESC descY(DXGI_FORMAT_A8_UNORM,
|
|
||||||
data->mYSize.width,
|
|
||||||
data->mYSize.height, 1, 1);
|
|
||||||
CD3D10_TEXTURE2D_DESC descCbCr(DXGI_FORMAT_A8_UNORM,
|
|
||||||
data->mCbCrSize.width,
|
|
||||||
data->mCbCrSize.height, 1, 1);
|
|
||||||
|
|
||||||
descY.Usage = descCbCr.Usage = D3D10_USAGE_IMMUTABLE;
|
|
||||||
|
|
||||||
dataY.pSysMem = data->mYChannel;
|
|
||||||
dataY.SysMemPitch = data->mYStride;
|
|
||||||
dataCb.pSysMem = data->mCbChannel;
|
|
||||||
dataCb.SysMemPitch = data->mCbCrStride;
|
|
||||||
dataCr.pSysMem = data->mCrChannel;
|
|
||||||
dataCr.SysMemPitch = data->mCbCrStride;
|
|
||||||
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&descY, &dataY, getter_AddRefs(backendData->mYTexture));
|
|
||||||
if (!FAILED(hr)) {
|
|
||||||
hr = device()->CreateTexture2D(&descCbCr, &dataCb, getter_AddRefs(backendData->mCbTexture));
|
|
||||||
}
|
|
||||||
if (!FAILED(hr)) {
|
|
||||||
hr = device()->CreateTexture2D(&descCbCr, &dataCr, getter_AddRefs(backendData->mCrTexture));
|
|
||||||
}
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("PlanarYCbCrImageD3D10::AllocateTextures(): Failed to create texture"),
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
device()->CreateShaderResourceView(backendData->mYTexture, nullptr, getter_AddRefs(backendData->mYView));
|
|
||||||
device()->CreateShaderResourceView(backendData->mCbTexture, nullptr, getter_AddRefs(backendData->mCbView));
|
|
||||||
device()->CreateShaderResourceView(backendData->mCrTexture, nullptr, getter_AddRefs(backendData->mCrView));
|
|
||||||
|
|
||||||
aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, backendData.forget());
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ID3D10ShaderResourceView>
|
|
||||||
ImageLayerD3D10::GetAsTexture(gfx::IntSize* aSize)
|
|
||||||
{
|
|
||||||
if (!GetContainer()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoLockImage autoLock(GetContainer());
|
|
||||||
|
|
||||||
Image *image = autoLock.GetImage();
|
|
||||||
if (!image) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image->GetFormat() != ImageFormat::CAIRO_SURFACE) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aSize = image->GetSize();
|
|
||||||
bool dontCare;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> result = GetImageSRView(image, dontCare);
|
|
||||||
return result.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
@ -1,60 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_IMAGELAYERD3D10_H
|
|
||||||
#define GFX_IMAGELAYERD3D10_H
|
|
||||||
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
#include "ImageLayers.h"
|
|
||||||
#include "ImageContainer.h"
|
|
||||||
#include "yuv_convert.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class ImageLayerD3D10 : public ImageLayer,
|
|
||||||
public LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageLayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: ImageLayer(aManager, nullptr)
|
|
||||||
, LayerD3D10(aManager)
|
|
||||||
{
|
|
||||||
mImplData = static_cast<LayerD3D10*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// LayerD3D10 Implementation
|
|
||||||
virtual Layer* GetLayer();
|
|
||||||
|
|
||||||
virtual void RenderLayer();
|
|
||||||
|
|
||||||
void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage);
|
|
||||||
|
|
||||||
virtual already_AddRefed<ID3D10ShaderResourceView> GetAsTexture(gfx::IntSize* aSize);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ID3D10ShaderResourceView* GetImageSRView(Image* aImage, bool& aHasAlpha,
|
|
||||||
IDXGIKeyedMutex **aMutex = nullptr);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PlanarYCbCrD3D10BackendData : public ImageBackendData
|
|
||||||
{
|
|
||||||
nsRefPtr<ID3D10Texture2D> mYTexture;
|
|
||||||
nsRefPtr<ID3D10Texture2D> mCrTexture;
|
|
||||||
nsRefPtr<ID3D10Texture2D> mCbTexture;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mYView;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mCbView;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mCrView;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextureD3D10BackendData : public ImageBackendData
|
|
||||||
{
|
|
||||||
nsRefPtr<ID3D10Texture2D> mTexture;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mSRView;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
#endif /* GFX_IMAGELAYERD3D10_H */
|
|
@ -1,888 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
#include "LayerManagerD3D10Effect.h"
|
|
||||||
#include "gfxWindowsPlatform.h"
|
|
||||||
#include "gfx2DGlue.h"
|
|
||||||
#include "gfxD2DSurface.h"
|
|
||||||
#include "gfxFailure.h"
|
|
||||||
#include "cairo-win32.h"
|
|
||||||
#include "dxgi.h"
|
|
||||||
|
|
||||||
#include "ContainerLayerD3D10.h"
|
|
||||||
#include "PaintedLayerD3D10.h"
|
|
||||||
#include "ColorLayerD3D10.h"
|
|
||||||
#include "CanvasLayerD3D10.h"
|
|
||||||
#include "ReadbackLayerD3D10.h"
|
|
||||||
#include "ImageLayerD3D10.h"
|
|
||||||
#include "mozilla/layers/PLayerChild.h"
|
|
||||||
#include "mozilla/WidgetUtils.h"
|
|
||||||
|
|
||||||
#include "../d3d9/Nv3DVUtils.h"
|
|
||||||
|
|
||||||
#include "gfxCrashReporterUtils.h"
|
|
||||||
#include "nsWindowsHelpers.h"
|
|
||||||
#ifdef MOZ_METRO
|
|
||||||
#include "DXGI1_2.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace mozilla::gfx;
|
|
||||||
|
|
||||||
struct Vertex
|
|
||||||
{
|
|
||||||
float position[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
// {592BF306-0EED-4F76-9D03-A0846450F472}
|
|
||||||
static const GUID sDeviceAttachments =
|
|
||||||
{ 0x592bf306, 0xeed, 0x4f76, { 0x9d, 0x3, 0xa0, 0x84, 0x64, 0x50, 0xf4, 0x72 } };
|
|
||||||
// {716AEDB1-C9C3-4B4D-8332-6F65D44AF6A8}
|
|
||||||
static const GUID sLayerManagerCount =
|
|
||||||
{ 0x716aedb1, 0xc9c3, 0x4b4d, { 0x83, 0x32, 0x6f, 0x65, 0xd4, 0x4a, 0xf6, 0xa8 } };
|
|
||||||
|
|
||||||
LayerManagerD3D10::LayerManagerD3D10(nsIWidget *aWidget)
|
|
||||||
: mWidget(aWidget)
|
|
||||||
, mDisableSequenceForNextFrame(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DeviceAttachments
|
|
||||||
{
|
|
||||||
nsRefPtr<ID3D10Effect> mEffect;
|
|
||||||
nsRefPtr<ID3D10InputLayout> mInputLayout;
|
|
||||||
nsRefPtr<ID3D10Buffer> mVertexBuffer;
|
|
||||||
nsRefPtr<ReadbackManagerD3D10> mReadbackManager;
|
|
||||||
};
|
|
||||||
|
|
||||||
LayerManagerD3D10::~LayerManagerD3D10()
|
|
||||||
{
|
|
||||||
if (mDevice) {
|
|
||||||
int referenceCount = 0;
|
|
||||||
UINT size = sizeof(referenceCount);
|
|
||||||
HRESULT hr = mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
|
|
||||||
NS_ASSERTION(SUCCEEDED(hr), "Reference count not found on device.");
|
|
||||||
referenceCount--;
|
|
||||||
mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);
|
|
||||||
|
|
||||||
if (!referenceCount) {
|
|
||||||
DeviceAttachments *attachments;
|
|
||||||
size = sizeof(attachments);
|
|
||||||
mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments);
|
|
||||||
// No LayerManagers left for this device. Clear out interfaces stored which
|
|
||||||
// hold a reference to the device.
|
|
||||||
mDevice->SetPrivateData(sDeviceAttachments, 0, nullptr);
|
|
||||||
|
|
||||||
delete attachments;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
SetHRESULT(HRESULT* aHresultPtr, HRESULT aHresult)
|
|
||||||
{
|
|
||||||
if (aHresultPtr) {
|
|
||||||
*aHresultPtr = aHresult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
LayerManagerD3D10::Initialize(bool force, HRESULT* aHresultPtr)
|
|
||||||
{
|
|
||||||
ScopedGfxFeatureReporter reporter("D3D10 Layers", force);
|
|
||||||
|
|
||||||
HRESULT hr = E_UNEXPECTED;
|
|
||||||
|
|
||||||
/* Create an Nv3DVUtils instance */
|
|
||||||
if (!mNv3DVUtils) {
|
|
||||||
mNv3DVUtils = new Nv3DVUtils();
|
|
||||||
if (!mNv3DVUtils) {
|
|
||||||
NS_WARNING("Could not create a new instance of Nv3DVUtils.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the Nv3DVUtils object */
|
|
||||||
if (mNv3DVUtils) {
|
|
||||||
mNv3DVUtils->Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
|
|
||||||
if (!mDevice) {
|
|
||||||
SetHRESULT(aHresultPtr, hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do some post device creation setup
|
|
||||||
*/
|
|
||||||
if (mNv3DVUtils) {
|
|
||||||
IUnknown* devUnknown = nullptr;
|
|
||||||
if (mDevice) {
|
|
||||||
mDevice->QueryInterface(IID_IUnknown, (void **)&devUnknown);
|
|
||||||
}
|
|
||||||
mNv3DVUtils->SetDeviceInfo(devUnknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
int referenceCount = 0;
|
|
||||||
UINT size = sizeof(referenceCount);
|
|
||||||
// If this isn't there yet it'll fail, count will remain 0, which is correct.
|
|
||||||
mDevice->GetPrivateData(sLayerManagerCount, &size, &referenceCount);
|
|
||||||
referenceCount++;
|
|
||||||
mDevice->SetPrivateData(sLayerManagerCount, sizeof(referenceCount), &referenceCount);
|
|
||||||
|
|
||||||
DeviceAttachments *attachments;
|
|
||||||
size = sizeof(DeviceAttachments*);
|
|
||||||
if (FAILED(mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments))) {
|
|
||||||
attachments = new DeviceAttachments;
|
|
||||||
mDevice->SetPrivateData(sDeviceAttachments, sizeof(attachments), &attachments);
|
|
||||||
|
|
||||||
SetLastError(0);
|
|
||||||
decltype(D3D10CreateEffectFromMemory)* createEffect =
|
|
||||||
(decltype(D3D10CreateEffectFromMemory)*)
|
|
||||||
GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateEffectFromMemory");
|
|
||||||
if (!createEffect) {
|
|
||||||
SetHRESULT(aHresultPtr, HRESULT_FROM_WIN32(GetLastError()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = createEffect((void*)g_main,
|
|
||||||
sizeof(g_main),
|
|
||||||
D3D10_EFFECT_SINGLE_THREADED,
|
|
||||||
mDevice,
|
|
||||||
nullptr,
|
|
||||||
getter_AddRefs(mEffect));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SetHRESULT(aHresultPtr, hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
attachments->mEffect = mEffect;
|
|
||||||
|
|
||||||
D3D10_INPUT_ELEMENT_DESC layout[] =
|
|
||||||
{
|
|
||||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
|
||||||
};
|
|
||||||
D3D10_PASS_DESC passDesc;
|
|
||||||
mEffect->GetTechniqueByName("RenderRGBLayerPremul")->GetPassByIndex(0)->
|
|
||||||
GetDesc(&passDesc);
|
|
||||||
|
|
||||||
hr = mDevice->CreateInputLayout(layout,
|
|
||||||
sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC),
|
|
||||||
passDesc.pIAInputSignature,
|
|
||||||
passDesc.IAInputSignatureSize,
|
|
||||||
getter_AddRefs(mInputLayout));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SetHRESULT(aHresultPtr, hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
attachments->mInputLayout = mInputLayout;
|
|
||||||
|
|
||||||
Vertex vertices[] = { {{0.0, 0.0}}, {{1.0, 0.0}}, {{0.0, 1.0}}, {{1.0, 1.0}} };
|
|
||||||
CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
|
|
||||||
D3D10_SUBRESOURCE_DATA data;
|
|
||||||
data.pSysMem = (void*)vertices;
|
|
||||||
|
|
||||||
hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SetHRESULT(aHresultPtr, hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
attachments->mVertexBuffer = mVertexBuffer;
|
|
||||||
} else {
|
|
||||||
mEffect = attachments->mEffect;
|
|
||||||
mVertexBuffer = attachments->mVertexBuffer;
|
|
||||||
mInputLayout = attachments->mInputLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<IDXGIDevice> dxgiDevice;
|
|
||||||
nsRefPtr<IDXGIAdapter> dxgiAdapter;
|
|
||||||
|
|
||||||
mDevice->QueryInterface(dxgiDevice.StartAssignment());
|
|
||||||
dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter));
|
|
||||||
|
|
||||||
#ifdef MOZ_METRO
|
|
||||||
if (IsRunningInWindowsMetro()) {
|
|
||||||
nsRefPtr<IDXGIFactory2> dxgiFactory;
|
|
||||||
dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
|
|
||||||
|
|
||||||
nsIntRect rect;
|
|
||||||
mWidget->GetClientBounds(rect);
|
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 swapDesc = { 0 };
|
|
||||||
// Automatically detect the width and the height from the winrt CoreWindow
|
|
||||||
swapDesc.Width = rect.width;
|
|
||||||
swapDesc.Height = rect.height;
|
|
||||||
// This is the most common swapchain format
|
|
||||||
swapDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
swapDesc.Stereo = false;
|
|
||||||
// Don't use multi-sampling
|
|
||||||
swapDesc.SampleDesc.Count = 1;
|
|
||||||
swapDesc.SampleDesc.Quality = 0;
|
|
||||||
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
// Use double buffering to enable flip
|
|
||||||
swapDesc.BufferCount = 2;
|
|
||||||
swapDesc.Scaling = DXGI_SCALING_NONE;
|
|
||||||
// All Metro style apps must use this SwapEffect
|
|
||||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
|
||||||
swapDesc.Flags = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a swap chain, this swap chain will contain the backbuffer for
|
|
||||||
* the window we draw to. The front buffer is the full screen front
|
|
||||||
* buffer.
|
|
||||||
*/
|
|
||||||
nsRefPtr<IDXGISwapChain1> swapChain1;
|
|
||||||
hr = dxgiFactory->CreateSwapChainForCoreWindow(
|
|
||||||
dxgiDevice, (IUnknown *)mWidget->GetNativeData(NS_NATIVE_ICOREWINDOW),
|
|
||||||
&swapDesc, nullptr, getter_AddRefs(swapChain1));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SetHRESULT(aHresultPtr, hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mSwapChain = swapChain1;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
nsRefPtr<IDXGIFactory> dxgiFactory;
|
|
||||||
dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.StartAssignment()));
|
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
|
||||||
::ZeroMemory(&swapDesc, sizeof(swapDesc));
|
|
||||||
swapDesc.BufferDesc.Width = 0;
|
|
||||||
swapDesc.BufferDesc.Height = 0;
|
|
||||||
swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
swapDesc.BufferDesc.RefreshRate.Numerator = 60;
|
|
||||||
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
|
|
||||||
swapDesc.SampleDesc.Count = 1;
|
|
||||||
swapDesc.SampleDesc.Quality = 0;
|
|
||||||
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
swapDesc.BufferCount = 1;
|
|
||||||
swapDesc.OutputWindow = (HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW);
|
|
||||||
swapDesc.Windowed = TRUE;
|
|
||||||
// We don't really need this flag, however it seems on some NVidia hardware
|
|
||||||
// smaller area windows do not present properly without this flag. This flag
|
|
||||||
// should have no negative consequences by itself. See bug 613790. This flag
|
|
||||||
// is broken on optimus devices. As a temporary solution we don't set it
|
|
||||||
// there, the only way of reliably detecting we're on optimus is looking for
|
|
||||||
// the DLL. See Bug 623807.
|
|
||||||
if (gfxWindowsPlatform::IsOptimus()) {
|
|
||||||
swapDesc.Flags = 0;
|
|
||||||
} else {
|
|
||||||
swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a swap chain, this swap chain will contain the backbuffer for
|
|
||||||
* the window we draw to. The front buffer is the full screen front
|
|
||||||
* buffer.
|
|
||||||
*/
|
|
||||||
hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, getter_AddRefs(mSwapChain));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need this because we don't want DXGI to respond to Alt+Enter.
|
|
||||||
dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow, DXGI_MWA_NO_WINDOW_CHANGES);
|
|
||||||
}
|
|
||||||
|
|
||||||
reporter.SetSuccessful();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::Destroy()
|
|
||||||
{
|
|
||||||
if (!IsDestroyed()) {
|
|
||||||
if (mRoot) {
|
|
||||||
static_cast<LayerD3D10*>(mRoot->ImplData())->LayerManagerDestroyed();
|
|
||||||
}
|
|
||||||
// XXX need to be careful here about surface destruction
|
|
||||||
// racing with share-to-chrome message
|
|
||||||
}
|
|
||||||
LayerManager::Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::SetRoot(Layer *aRoot)
|
|
||||||
{
|
|
||||||
mRoot = aRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::BeginTransaction()
|
|
||||||
{
|
|
||||||
mInTransaction = true;
|
|
||||||
|
|
||||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
|
||||||
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
|
|
||||||
Log();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::BeginTransactionWithTarget(gfxContext* aTarget)
|
|
||||||
{
|
|
||||||
mInTransaction = true;
|
|
||||||
mTarget = aTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
LayerManagerD3D10::EndEmptyTransaction(EndTransactionFlags aFlags)
|
|
||||||
{
|
|
||||||
mInTransaction = false;
|
|
||||||
|
|
||||||
if (!mRoot)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
EndTransaction(nullptr, nullptr, aFlags);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::EndTransaction(DrawPaintedLayerCallback aCallback,
|
|
||||||
void* aCallbackData,
|
|
||||||
EndTransactionFlags aFlags)
|
|
||||||
{
|
|
||||||
mInTransaction = false;
|
|
||||||
|
|
||||||
if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
|
|
||||||
mCurrentCallbackInfo.Callback = aCallback;
|
|
||||||
mCurrentCallbackInfo.CallbackData = aCallbackData;
|
|
||||||
|
|
||||||
if (aFlags & END_NO_COMPOSITE) {
|
|
||||||
// Apply pending tree updates before recomputing effective
|
|
||||||
// properties.
|
|
||||||
mRoot->ApplyPendingUpdatesToSubtree();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The results of our drawing always go directly into a pixel buffer,
|
|
||||||
// so we don't need to pass any global transform here.
|
|
||||||
mRoot->ComputeEffectiveTransforms(Matrix4x4());
|
|
||||||
|
|
||||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
|
||||||
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
|
|
||||||
Log();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Render(aFlags);
|
|
||||||
mCurrentCallbackInfo.Callback = nullptr;
|
|
||||||
mCurrentCallbackInfo.CallbackData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
|
||||||
Log();
|
|
||||||
MOZ_LAYERS_LOG(("]----- EndTransaction"));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mTarget = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<PaintedLayer>
|
|
||||||
LayerManagerD3D10::CreatePaintedLayer()
|
|
||||||
{
|
|
||||||
nsRefPtr<PaintedLayer> layer = new PaintedLayerD3D10(this);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ContainerLayer>
|
|
||||||
LayerManagerD3D10::CreateContainerLayer()
|
|
||||||
{
|
|
||||||
nsRefPtr<ContainerLayer> layer = new ContainerLayerD3D10(this);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ImageLayer>
|
|
||||||
LayerManagerD3D10::CreateImageLayer()
|
|
||||||
{
|
|
||||||
nsRefPtr<ImageLayer> layer = new ImageLayerD3D10(this);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ColorLayer>
|
|
||||||
LayerManagerD3D10::CreateColorLayer()
|
|
||||||
{
|
|
||||||
nsRefPtr<ColorLayer> layer = new ColorLayerD3D10(this);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<CanvasLayer>
|
|
||||||
LayerManagerD3D10::CreateCanvasLayer()
|
|
||||||
{
|
|
||||||
nsRefPtr<CanvasLayer> layer = new CanvasLayerD3D10(this);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ReadbackLayer>
|
|
||||||
LayerManagerD3D10::CreateReadbackLayer()
|
|
||||||
{
|
|
||||||
nsRefPtr<ReadbackLayer> layer = new ReadbackLayerD3D10(this);
|
|
||||||
return layer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
TemporaryRef<DrawTarget>
|
|
||||||
LayerManagerD3D10::CreateOptimalDrawTarget(const IntSize &aSize,
|
|
||||||
SurfaceFormat aFormat)
|
|
||||||
{
|
|
||||||
if ((aFormat != SurfaceFormat::B8G8R8X8 &&
|
|
||||||
aFormat != SurfaceFormat::B8G8R8A8)) {
|
|
||||||
return LayerManager::CreateOptimalDrawTarget(aSize, aFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Texture2D> texture;
|
|
||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
|
||||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
|
||||||
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
|
|
||||||
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create new texture for CreateOptimalDrawTarget!");
|
|
||||||
return LayerManager::CreateOptimalDrawTarget(aSize, aFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<DrawTarget> dt =
|
|
||||||
Factory::CreateDrawTargetForD3D10Texture(texture, aFormat);
|
|
||||||
|
|
||||||
if (!dt) {
|
|
||||||
return LayerManager::CreateOptimalDrawTarget(aSize, aFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TemporaryRef<DrawTarget>
|
|
||||||
LayerManagerD3D10::CreateOptimalMaskDrawTarget(const IntSize &aSize)
|
|
||||||
{
|
|
||||||
return CreateOptimalDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TemporaryRef<DrawTarget>
|
|
||||||
LayerManagerD3D10::CreateDrawTarget(const IntSize &aSize,
|
|
||||||
SurfaceFormat aFormat)
|
|
||||||
{
|
|
||||||
if ((aFormat != SurfaceFormat::B8G8R8A8 &&
|
|
||||||
aFormat != SurfaceFormat::B8G8R8X8) ||
|
|
||||||
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() != BackendType::DIRECT2D) {
|
|
||||||
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Texture2D> texture;
|
|
||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
|
||||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
|
||||||
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create new texture for CreateOptimalDrawTarget!");
|
|
||||||
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<DrawTarget> surface =
|
|
||||||
Factory::CreateDrawTargetForD3D10Texture(texture, aFormat);
|
|
||||||
|
|
||||||
if (!surface) {
|
|
||||||
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadbackManagerD3D10*
|
|
||||||
LayerManagerD3D10::readbackManager()
|
|
||||||
{
|
|
||||||
EnsureReadbackManager();
|
|
||||||
return mReadbackManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::SetViewport(const nsIntSize &aViewport)
|
|
||||||
{
|
|
||||||
mViewport = aViewport;
|
|
||||||
|
|
||||||
D3D10_VIEWPORT viewport;
|
|
||||||
viewport.MaxDepth = 1.0f;
|
|
||||||
viewport.MinDepth = 0;
|
|
||||||
viewport.Width = aViewport.width;
|
|
||||||
viewport.Height = aViewport.height;
|
|
||||||
viewport.TopLeftX = 0;
|
|
||||||
viewport.TopLeftY = 0;
|
|
||||||
|
|
||||||
mDevice->RSSetViewports(1, &viewport);
|
|
||||||
|
|
||||||
gfx3DMatrix projection;
|
|
||||||
/*
|
|
||||||
* Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
|
|
||||||
* <1.0, -1.0> bottomright)
|
|
||||||
*/
|
|
||||||
projection._11 = 2.0f / aViewport.width;
|
|
||||||
projection._22 = -2.0f / aViewport.height;
|
|
||||||
projection._33 = 0.0f;
|
|
||||||
projection._41 = -1.0f;
|
|
||||||
projection._42 = 1.0f;
|
|
||||||
projection._44 = 1.0f;
|
|
||||||
|
|
||||||
HRESULT hr = mEffect->GetVariableByName("mProjection")->
|
|
||||||
SetRawValue(&projection._11, 0, 64);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to set projection matrix.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::SetupInputAssembler()
|
|
||||||
{
|
|
||||||
mDevice->IASetInputLayout(mInputLayout);
|
|
||||||
|
|
||||||
UINT stride = sizeof(Vertex);
|
|
||||||
UINT offset = 0;
|
|
||||||
ID3D10Buffer *buffer = mVertexBuffer;
|
|
||||||
mDevice->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
|
|
||||||
mDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::SetupPipeline()
|
|
||||||
{
|
|
||||||
VerifyBufferSize();
|
|
||||||
UpdateRenderTarget();
|
|
||||||
|
|
||||||
nsIntRect rect;
|
|
||||||
mWidget->GetClientBounds(rect);
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
hr = mEffect->GetVariableByName("vTextureCoords")->AsVector()->
|
|
||||||
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to set Texture Coordinates.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D10RenderTargetView *view = mRTView;
|
|
||||||
mDevice->OMSetRenderTargets(1, &view, nullptr);
|
|
||||||
|
|
||||||
SetupInputAssembler();
|
|
||||||
|
|
||||||
SetViewport(nsIntSize(rect.width, rect.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::UpdateRenderTarget()
|
|
||||||
{
|
|
||||||
if (mRTView || !mSwapChain) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Texture2D> backBuf;
|
|
||||||
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mDevice->CreateRenderTargetView(backBuf, nullptr, getter_AddRefs(mRTView));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::VerifyBufferSize()
|
|
||||||
{
|
|
||||||
nsIntRect rect;
|
|
||||||
mWidget->GetClientBounds(rect);
|
|
||||||
|
|
||||||
if (mSwapChain) {
|
|
||||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
|
||||||
mSwapChain->GetDesc(&swapDesc);
|
|
||||||
|
|
||||||
if (swapDesc.BufferDesc.Width == rect.width &&
|
|
||||||
swapDesc.BufferDesc.Height == rect.height) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mRTView = nullptr;
|
|
||||||
if (IsRunningInWindowsMetro()) {
|
|
||||||
mSwapChain->ResizeBuffers(2, rect.width, rect.height,
|
|
||||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
|
||||||
0);
|
|
||||||
mDisableSequenceForNextFrame = true;
|
|
||||||
} else if (gfxWindowsPlatform::IsOptimus()) {
|
|
||||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
|
||||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
|
||||||
0);
|
|
||||||
} else {
|
|
||||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
|
||||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
|
||||||
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::EnsureReadbackManager()
|
|
||||||
{
|
|
||||||
if (mReadbackManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceAttachments *attachments;
|
|
||||||
UINT size = sizeof(DeviceAttachments*);
|
|
||||||
if (FAILED(mDevice->GetPrivateData(sDeviceAttachments, &size, &attachments))) {
|
|
||||||
// Strange! This shouldn't happen ... return a readback manager for this
|
|
||||||
// layer manager only.
|
|
||||||
mReadbackManager = new ReadbackManagerD3D10();
|
|
||||||
gfx::LogFailure(NS_LITERAL_CSTRING("Couldn't get device attachments for device."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachments->mReadbackManager) {
|
|
||||||
mReadbackManager = attachments->mReadbackManager;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mReadbackManager = new ReadbackManagerD3D10();
|
|
||||||
attachments->mReadbackManager = mReadbackManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::Render(EndTransactionFlags aFlags)
|
|
||||||
{
|
|
||||||
static_cast<LayerD3D10*>(mRoot->ImplData())->Validate();
|
|
||||||
|
|
||||||
if (aFlags & END_NO_COMPOSITE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetupPipeline();
|
|
||||||
|
|
||||||
float black[] = { 0, 0, 0, 0 };
|
|
||||||
device()->ClearRenderTargetView(mRTView, black);
|
|
||||||
|
|
||||||
nsIntRect rect;
|
|
||||||
mWidget->GetClientBounds(rect);
|
|
||||||
|
|
||||||
const nsIntRect *clipRect = mRoot->GetClipRect();
|
|
||||||
D3D10_RECT r;
|
|
||||||
if (clipRect) {
|
|
||||||
r.left = (LONG)clipRect->x;
|
|
||||||
r.top = (LONG)clipRect->y;
|
|
||||||
r.right = (LONG)(clipRect->x + clipRect->width);
|
|
||||||
r.bottom = (LONG)(clipRect->y + clipRect->height);
|
|
||||||
} else {
|
|
||||||
r.left = r.top = 0;
|
|
||||||
r.right = rect.width;
|
|
||||||
r.bottom = rect.height;
|
|
||||||
}
|
|
||||||
device()->RSSetScissorRects(1, &r);
|
|
||||||
|
|
||||||
static_cast<LayerD3D10*>(mRoot->ImplData())->RenderLayer();
|
|
||||||
|
|
||||||
if (!mRegionToClear.IsEmpty()) {
|
|
||||||
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
||||||
gfx::Matrix4x4 transform;
|
|
||||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform, 0, 64);
|
|
||||||
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
|
|
||||||
|
|
||||||
ID3D10EffectTechnique *technique = effect()->GetTechniqueByName("RenderClearLayer");
|
|
||||||
|
|
||||||
nsIntRegionRectIterator iter(mRegionToClear);
|
|
||||||
const nsIntRect *r;
|
|
||||||
while ((r = iter.Next())) {
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)r->x,
|
|
||||||
(float)r->y,
|
|
||||||
(float)r->width,
|
|
||||||
(float)r->height)
|
|
||||||
);
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See bug 630197 - we have some reasons to believe if an earlier call
|
|
||||||
// returned an error, the upcoming present call may raise an exception.
|
|
||||||
// This will check if any of the calls done recently has returned an error
|
|
||||||
// and bails on composition. On the -next- frame we will then abandon
|
|
||||||
// hardware acceleration from gfxWindowsPlatform::VerifyD2DDevice.
|
|
||||||
// This might not be the 'optimal' solution but it will help us assert
|
|
||||||
// whether our thoughts of the causes of the issues are correct.
|
|
||||||
if (FAILED(mDevice->GetDeviceRemovedReason())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTarget) {
|
|
||||||
PaintToTarget();
|
|
||||||
} else {
|
|
||||||
mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
|
|
||||||
mDisableSequenceForNextFrame = false;
|
|
||||||
}
|
|
||||||
RecordFrame();
|
|
||||||
PostPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::PaintToTarget()
|
|
||||||
{
|
|
||||||
nsRefPtr<ID3D10Texture2D> backBuf;
|
|
||||||
|
|
||||||
mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
|
|
||||||
|
|
||||||
D3D10_TEXTURE2D_DESC bbDesc;
|
|
||||||
backBuf->GetDesc(&bbDesc);
|
|
||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height);
|
|
||||||
softDesc.MipLevels = 1;
|
|
||||||
softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
|
|
||||||
softDesc.Usage = D3D10_USAGE_STAGING;
|
|
||||||
softDesc.BindFlags = 0;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Texture2D> readTexture;
|
|
||||||
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&softDesc, nullptr, getter_AddRefs(readTexture));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
ReportFailure(NS_LITERAL_CSTRING("LayerManagerD3D10::PaintToTarget(): Failed to create texture"),
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
device()->CopyResource(readTexture, backBuf);
|
|
||||||
|
|
||||||
D3D10_MAPPED_TEXTURE2D map;
|
|
||||||
readTexture->Map(0, D3D10_MAP_READ, 0, &map);
|
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> tmpSurface =
|
|
||||||
new gfxImageSurface((unsigned char*)map.pData,
|
|
||||||
gfxIntSize(bbDesc.Width, bbDesc.Height),
|
|
||||||
map.RowPitch,
|
|
||||||
gfxImageFormat::ARGB32);
|
|
||||||
|
|
||||||
mTarget->SetSource(tmpSurface);
|
|
||||||
mTarget->SetOperator(gfxContext::OPERATOR_OVER);
|
|
||||||
mTarget->Paint();
|
|
||||||
|
|
||||||
readTexture->Unmap(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerD3D10::ReportFailure(const nsACString &aMsg, HRESULT aCode)
|
|
||||||
{
|
|
||||||
// We could choose to abort here when hr == E_OUTOFMEMORY.
|
|
||||||
nsCString msg;
|
|
||||||
msg.Append(aMsg);
|
|
||||||
msg.AppendLiteral(" Error code: ");
|
|
||||||
msg.AppendInt(uint32_t(aCode));
|
|
||||||
NS_WARNING(msg.BeginReading());
|
|
||||||
|
|
||||||
gfx::LogFailure(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerD3D10::LayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: mD3DManager(aManager)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D10EffectTechnique*
|
|
||||||
LayerD3D10::SelectShader(uint8_t aFlags)
|
|
||||||
{
|
|
||||||
switch (aFlags) {
|
|
||||||
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_LINEAR | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerNonPremulMask");
|
|
||||||
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerNonPremul");
|
|
||||||
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_POINT | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint");
|
|
||||||
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_POINT | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerNonPremulPointMask");
|
|
||||||
case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK_3D):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerPremulMask3D");
|
|
||||||
case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
|
|
||||||
case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerPremul");
|
|
||||||
case (SHADER_RGBA | SHADER_PREMUL | SHADER_POINT | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerPremulPointMask");
|
|
||||||
case (SHADER_RGBA | SHADER_PREMUL | SHADER_POINT | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
|
|
||||||
case (SHADER_RGB | SHADER_PREMUL | SHADER_POINT | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBLayerPremulPointMask");
|
|
||||||
case (SHADER_RGB | SHADER_PREMUL | SHADER_POINT | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
|
|
||||||
case (SHADER_RGB | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
|
|
||||||
case (SHADER_RGB | SHADER_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderRGBLayerPremul");
|
|
||||||
case (SHADER_SOLID | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderSolidColorLayerMask");
|
|
||||||
case (SHADER_SOLID | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderSolidColorLayer");
|
|
||||||
case (SHADER_COMPONENT_ALPHA | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderComponentAlphaLayerMask");
|
|
||||||
case (SHADER_COMPONENT_ALPHA | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderComponentAlphaLayer");
|
|
||||||
case (SHADER_YCBCR | SHADER_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderYCbCrLayerMask");
|
|
||||||
case (SHADER_YCBCR | SHADER_NO_MASK):
|
|
||||||
return effect()->GetTechniqueByName("RenderYCbCrLayer");
|
|
||||||
default:
|
|
||||||
NS_ERROR("Invalid shader.");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
LayerD3D10::LoadMaskTexture()
|
|
||||||
{
|
|
||||||
if (Layer* maskLayer = GetLayer()->GetMaskLayer()) {
|
|
||||||
IntSize size;
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> maskSRV =
|
|
||||||
static_cast<LayerD3D10*>(maskLayer->ImplData())->GetAsTexture(&size);
|
|
||||||
|
|
||||||
if (!maskSRV) {
|
|
||||||
return SHADER_NO_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix maskTransform;
|
|
||||||
Matrix4x4 effectiveTransform = maskLayer->GetEffectiveTransform();
|
|
||||||
bool maskIs2D = effectiveTransform.CanDraw2D(&maskTransform);
|
|
||||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
|
||||||
Rect bounds = Rect(Point(), Size(size));
|
|
||||||
bounds = maskTransform.TransformBounds(bounds);
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vMaskQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)bounds.x,
|
|
||||||
(float)bounds.y,
|
|
||||||
(float)bounds.width,
|
|
||||||
(float)bounds.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
effect()->GetVariableByName("tMask")->AsShaderResource()->SetResource(maskSRV);
|
|
||||||
return SHADER_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SHADER_NO_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,605 +0,0 @@
|
|||||||
typedef float4 rect;
|
|
||||||
cbuffer PerLayer {
|
|
||||||
rect vTextureCoords;
|
|
||||||
rect vLayerQuad;
|
|
||||||
rect vMaskQuad;
|
|
||||||
float fLayerOpacity;
|
|
||||||
float4x4 mLayerTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
cbuffer PerOccasionalLayer {
|
|
||||||
float4 vRenderTargetOffset;
|
|
||||||
float4 fLayerColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
cbuffer PerLayerManager {
|
|
||||||
float4x4 mProjection;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlendState Premul
|
|
||||||
{
|
|
||||||
AlphaToCoverageEnable = FALSE;
|
|
||||||
BlendEnable[0] = TRUE;
|
|
||||||
SrcBlend = One;
|
|
||||||
DestBlend = Inv_Src_Alpha;
|
|
||||||
BlendOp = Add;
|
|
||||||
SrcBlendAlpha = One;
|
|
||||||
DestBlendAlpha = Inv_Src_Alpha;
|
|
||||||
BlendOpAlpha = Add;
|
|
||||||
RenderTargetWriteMask[0] = 0x0F; // All
|
|
||||||
};
|
|
||||||
|
|
||||||
BlendState NonPremul
|
|
||||||
{
|
|
||||||
AlphaToCoverageEnable = FALSE;
|
|
||||||
BlendEnable[0] = TRUE;
|
|
||||||
SrcBlend = Src_Alpha;
|
|
||||||
DestBlend = Inv_Src_Alpha;
|
|
||||||
BlendOp = Add;
|
|
||||||
SrcBlendAlpha = One;
|
|
||||||
DestBlendAlpha = Inv_Src_Alpha;
|
|
||||||
BlendOpAlpha = Add;
|
|
||||||
RenderTargetWriteMask[0] = 0x0F; // All
|
|
||||||
};
|
|
||||||
|
|
||||||
BlendState NoBlendDual
|
|
||||||
{
|
|
||||||
AlphaToCoverageEnable = FALSE;
|
|
||||||
BlendEnable[0] = FALSE;
|
|
||||||
BlendEnable[1] = FALSE;
|
|
||||||
RenderTargetWriteMask[0] = 0x0F; // All
|
|
||||||
RenderTargetWriteMask[1] = 0x0F; // All
|
|
||||||
};
|
|
||||||
|
|
||||||
BlendState ComponentAlphaBlend
|
|
||||||
{
|
|
||||||
AlphaToCoverageEnable = FALSE;
|
|
||||||
BlendEnable[0] = TRUE;
|
|
||||||
SrcBlend = One;
|
|
||||||
DestBlend = Inv_Src1_Color;
|
|
||||||
BlendOp = Add;
|
|
||||||
SrcBlendAlpha = One;
|
|
||||||
DestBlendAlpha = Inv_Src_Alpha;
|
|
||||||
BlendOpAlpha = Add;
|
|
||||||
RenderTargetWriteMask[0] = 0x0F; // All
|
|
||||||
};
|
|
||||||
|
|
||||||
RasterizerState LayerRast
|
|
||||||
{
|
|
||||||
ScissorEnable = True;
|
|
||||||
CullMode = None;
|
|
||||||
};
|
|
||||||
|
|
||||||
Texture2D tRGB;
|
|
||||||
Texture2D tY;
|
|
||||||
Texture2D tCb;
|
|
||||||
Texture2D tCr;
|
|
||||||
Texture2D tRGBWhite;
|
|
||||||
Texture2D tMask;
|
|
||||||
|
|
||||||
SamplerState LayerTextureSamplerLinear
|
|
||||||
{
|
|
||||||
Filter = MIN_MAG_MIP_LINEAR;
|
|
||||||
AddressU = Clamp;
|
|
||||||
AddressV = Clamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
SamplerState LayerTextureSamplerPoint
|
|
||||||
{
|
|
||||||
Filter = MIN_MAG_MIP_POINT;
|
|
||||||
AddressU = Clamp;
|
|
||||||
AddressV = Clamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VS_INPUT {
|
|
||||||
float2 vPosition : POSITION;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VS_OUTPUT {
|
|
||||||
float4 vPosition : SV_Position;
|
|
||||||
float2 vTexCoords : TEXCOORD0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VS_MASK_OUTPUT {
|
|
||||||
float4 vPosition : SV_Position;
|
|
||||||
float2 vTexCoords : TEXCOORD0;
|
|
||||||
float2 vMaskCoords : TEXCOORD1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VS_MASK_3D_OUTPUT {
|
|
||||||
float4 vPosition : SV_Position;
|
|
||||||
float2 vTexCoords : TEXCOORD0;
|
|
||||||
float3 vMaskCoords : TEXCOORD1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS_OUTPUT {
|
|
||||||
float4 vSrc;
|
|
||||||
float4 vAlpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS_DUAL_OUTPUT {
|
|
||||||
float4 vOutput1 : SV_Target0;
|
|
||||||
float4 vOutput2 : SV_Target1;
|
|
||||||
};
|
|
||||||
|
|
||||||
float2 TexCoords(const float2 aPosition)
|
|
||||||
{
|
|
||||||
float2 result;
|
|
||||||
const float2 size = vTextureCoords.zw;
|
|
||||||
result.x = vTextureCoords.x + aPosition.x * size.x;
|
|
||||||
result.y = vTextureCoords.y + aPosition.y * size.y;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 TransformedPostion(float2 aInPosition)
|
|
||||||
{
|
|
||||||
// the current vertex's position on the quad
|
|
||||||
float4 position = float4(0, 0, 0, 1);
|
|
||||||
|
|
||||||
// We use 4 component floats to uniquely describe a rectangle, by the structure
|
|
||||||
// of x, y, width, height. This allows us to easily generate the 4 corners
|
|
||||||
// of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the
|
|
||||||
// stream source for our LayerQuad vertex shader. We do this by doing:
|
|
||||||
// Xout = x + Xin * width
|
|
||||||
// Yout = y + Yin * height
|
|
||||||
float2 size = vLayerQuad.zw;
|
|
||||||
position.x = vLayerQuad.x + aInPosition.x * size.x;
|
|
||||||
position.y = vLayerQuad.y + aInPosition.y * size.y;
|
|
||||||
|
|
||||||
position = mul(mLayerTransform, position);
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 VertexPosition(float4 aTransformedPosition)
|
|
||||||
{
|
|
||||||
float4 result;
|
|
||||||
result.w = aTransformedPosition.w;
|
|
||||||
result.xyz = aTransformedPosition.xyz / aTransformedPosition.w;
|
|
||||||
result -= vRenderTargetOffset;
|
|
||||||
result.xyz *= result.w;
|
|
||||||
|
|
||||||
result = mul(mProjection, result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
|
|
||||||
{
|
|
||||||
VS_OUTPUT outp;
|
|
||||||
float4 position = TransformedPostion(aVertex.vPosition);
|
|
||||||
|
|
||||||
outp.vPosition = VertexPosition(position);
|
|
||||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
|
||||||
|
|
||||||
return outp;
|
|
||||||
}
|
|
||||||
|
|
||||||
VS_MASK_OUTPUT LayerQuadMaskVS(const VS_INPUT aVertex)
|
|
||||||
{
|
|
||||||
VS_MASK_OUTPUT outp;
|
|
||||||
float4 position = TransformedPostion(aVertex.vPosition);
|
|
||||||
|
|
||||||
outp.vPosition = VertexPosition(position);
|
|
||||||
|
|
||||||
// calculate the position on the mask texture
|
|
||||||
outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
|
|
||||||
outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
|
|
||||||
|
|
||||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
|
||||||
|
|
||||||
return outp;
|
|
||||||
}
|
|
||||||
|
|
||||||
VS_MASK_3D_OUTPUT LayerQuadMask3DVS(const VS_INPUT aVertex)
|
|
||||||
{
|
|
||||||
VS_MASK_3D_OUTPUT outp;
|
|
||||||
float4 position = TransformedPostion(aVertex.vPosition);
|
|
||||||
|
|
||||||
outp.vPosition = VertexPosition(position);
|
|
||||||
|
|
||||||
// calculate the position on the mask texture
|
|
||||||
position.xyz /= position.w;
|
|
||||||
outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
|
|
||||||
outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
|
|
||||||
// We use the w coord to do non-perspective correct interpolation:
|
|
||||||
// the quad might be transformed in 3D, in which case it will have some
|
|
||||||
// perspective. The graphics card will do perspective-correct interpolation
|
|
||||||
// of the texture, but our mask is already transformed and so we require
|
|
||||||
// linear interpolation. Therefore, we must correct the interpolation
|
|
||||||
// ourselves, we do this by multiplying all coords by w here, and dividing by
|
|
||||||
// w in the pixel shader (post-interpolation), we pass w in outp.vMaskCoords.z.
|
|
||||||
// See http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness
|
|
||||||
outp.vMaskCoords.z = 1;
|
|
||||||
outp.vMaskCoords *= position.w;
|
|
||||||
|
|
||||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
|
||||||
|
|
||||||
return outp;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 RGBAShaderMask(const VS_MASK_OUTPUT aVertex, uniform sampler aSampler) : SV_Target
|
|
||||||
{
|
|
||||||
float2 maskCoords = aVertex.vMaskCoords;
|
|
||||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
|
||||||
return tRGB.Sample(aSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 RGBAShaderLinearMask3D(const VS_MASK_3D_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
|
||||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
|
||||||
return tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) * fLayerOpacity * mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 RGBShaderMask(const VS_MASK_OUTPUT aVertex, uniform sampler aSampler) : SV_Target
|
|
||||||
{
|
|
||||||
float4 result;
|
|
||||||
result = tRGB.Sample(aSampler, aVertex.vTexCoords) * fLayerOpacity;
|
|
||||||
result.a = fLayerOpacity;
|
|
||||||
|
|
||||||
float2 maskCoords = aVertex.vMaskCoords;
|
|
||||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
|
||||||
return result * mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* From Rec601:
|
|
||||||
[R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16]
|
|
||||||
[G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128]
|
|
||||||
[B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128]
|
|
||||||
|
|
||||||
For [0,1] instead of [0,255], and to 5 places:
|
|
||||||
[R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275]
|
|
||||||
[G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196]
|
|
||||||
[B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196]
|
|
||||||
*/
|
|
||||||
|
|
||||||
float4 CalculateYCbCrColor(const float2 aTexCoords)
|
|
||||||
{
|
|
||||||
float4 yuv;
|
|
||||||
float4 color;
|
|
||||||
|
|
||||||
yuv.r = tCr.Sample(LayerTextureSamplerLinear, aTexCoords).a - 0.50196;
|
|
||||||
yuv.g = tY.Sample(LayerTextureSamplerLinear, aTexCoords).a - 0.06275;
|
|
||||||
yuv.b = tCb.Sample(LayerTextureSamplerLinear, aTexCoords).a - 0.50196;
|
|
||||||
|
|
||||||
color.r = yuv.g * 1.16438 + yuv.r * 1.59603;
|
|
||||||
color.g = yuv.g * 1.16438 - 0.81297 * yuv.r - 0.39176 * yuv.b;
|
|
||||||
color.b = yuv.g * 1.16438 + yuv.b * 2.01723;
|
|
||||||
color.a = 1.0f;
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
float2 maskCoords = aVertex.vMaskCoords;
|
|
||||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
|
||||||
|
|
||||||
return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
PS_OUTPUT ComponentAlphaShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
PS_OUTPUT result;
|
|
||||||
|
|
||||||
result.vSrc = tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords);
|
|
||||||
result.vAlpha = 1.0 - tRGBWhite.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) + result.vSrc;
|
|
||||||
result.vSrc.a = result.vAlpha.g;
|
|
||||||
|
|
||||||
float2 maskCoords = aVertex.vMaskCoords;
|
|
||||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
|
||||||
result.vSrc *= fLayerOpacity * mask;
|
|
||||||
result.vAlpha *= fLayerOpacity * mask;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 SolidColorShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
float2 maskCoords = aVertex.vMaskCoords;
|
|
||||||
float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
|
|
||||||
return fLayerColor * mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Un-masked versions
|
|
||||||
*************************************************************
|
|
||||||
*/
|
|
||||||
float4 RGBAShader(const VS_OUTPUT aVertex, uniform sampler aSampler) : SV_Target
|
|
||||||
{
|
|
||||||
return tRGB.Sample(aSampler, aVertex.vTexCoords) * fLayerOpacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 RGBShader(const VS_OUTPUT aVertex, uniform sampler aSampler) : SV_Target
|
|
||||||
{
|
|
||||||
float4 result;
|
|
||||||
result = tRGB.Sample(aSampler, aVertex.vTexCoords) * fLayerOpacity;
|
|
||||||
result.a = fLayerOpacity;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
PS_OUTPUT ComponentAlphaShader(const VS_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
PS_OUTPUT result;
|
|
||||||
|
|
||||||
result.vSrc = tRGB.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords);
|
|
||||||
result.vAlpha = 1.0 - tRGBWhite.Sample(LayerTextureSamplerLinear, aVertex.vTexCoords) + result.vSrc;
|
|
||||||
result.vSrc.a = result.vAlpha.g;
|
|
||||||
result.vSrc *= fLayerOpacity;
|
|
||||||
result.vAlpha *= fLayerOpacity;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target
|
|
||||||
{
|
|
||||||
return fLayerColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
PS_DUAL_OUTPUT AlphaExtractionPrepareShader(const VS_OUTPUT aVertex)
|
|
||||||
{
|
|
||||||
PS_DUAL_OUTPUT result;
|
|
||||||
result.vOutput1 = float4(0, 0, 0, 1);
|
|
||||||
result.vOutput2 = float4(1, 1, 1, 1);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBLayerPremul
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShader(LayerTextureSamplerLinear) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBLayerPremulPoint
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShader(LayerTextureSamplerPoint) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerPremul
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShader(LayerTextureSamplerLinear) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerNonPremul
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShader(LayerTextureSamplerLinear) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerPremulPoint
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShader(LayerTextureSamplerPoint) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerNonPremulPoint
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShader(LayerTextureSamplerPoint) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderYCbCrLayer
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, YCbCrShader() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderComponentAlphaLayer
|
|
||||||
{
|
|
||||||
Pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( ComponentAlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, ComponentAlphaShader() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderSolidColorLayer
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, SolidColorShader() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderClearLayer
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( NoBlendDual, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, SolidColorShader() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 PrepareAlphaExtractionTextures
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( NoBlendDual, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, AlphaExtractionPrepareShader() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBLayerPremulMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShaderMask(LayerTextureSamplerLinear) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBLayerPremulPointMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBShaderMask(LayerTextureSamplerPoint) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerPremulMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderMask(LayerTextureSamplerLinear) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerPremulMask3D
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMask3DVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderLinearMask3D() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerNonPremulMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderMask(LayerTextureSamplerLinear) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerPremulPointMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderMask(LayerTextureSamplerPoint) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderRGBALayerNonPremulPointMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( NonPremul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, RGBAShaderMask(LayerTextureSamplerPoint) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderYCbCrLayerMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, YCbCrShaderMask() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderComponentAlphaLayerMask
|
|
||||||
{
|
|
||||||
Pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( ComponentAlphaBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, ComponentAlphaShaderMask() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique10 RenderSolidColorLayerMask
|
|
||||||
{
|
|
||||||
pass P0
|
|
||||||
{
|
|
||||||
SetRasterizerState( LayerRast );
|
|
||||||
SetBlendState( Premul, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
|
|
||||||
SetVertexShader( CompileShader( vs_4_0_level_9_3, LayerQuadMaskVS() ) );
|
|
||||||
SetGeometryShader( NULL );
|
|
||||||
SetPixelShader( CompileShader( ps_4_0_level_9_3, SolidColorShaderMask() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,288 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_LAYERMANAGERD3D10_H
|
|
||||||
#define GFX_LAYERMANAGERD3D10_H
|
|
||||||
|
|
||||||
#include "Layers.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <d3d10_1.h>
|
|
||||||
|
|
||||||
#include "gfxContext.h"
|
|
||||||
#include "mozilla/gfx/UserData.h"
|
|
||||||
#include "nsIWidget.h"
|
|
||||||
|
|
||||||
#include "ReadbackManagerD3D10.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class DummyRoot;
|
|
||||||
class Nv3DVUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This structure is used to pass rectangles to our shader constant. We can use
|
|
||||||
* this for passing rectangular areas to SetVertexShaderConstant. In the format
|
|
||||||
* of a 4 component float(x,y,width,height). Our vertex shader can then use
|
|
||||||
* this to construct rectangular positions from the 0,0-1,1 quad that we source
|
|
||||||
* it with.
|
|
||||||
*/
|
|
||||||
struct ShaderConstantRectD3D10
|
|
||||||
{
|
|
||||||
float mX, mY, mWidth, mHeight;
|
|
||||||
ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight)
|
|
||||||
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
// For easy passing to SetVertexShaderConstantF.
|
|
||||||
operator float* () { return &mX; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the LayerManager used for Direct3D 10. For now this will
|
|
||||||
* render on the main thread.
|
|
||||||
*
|
|
||||||
* For the time being, LayerManagerD3D10 forwards layers
|
|
||||||
* transactions.
|
|
||||||
*/
|
|
||||||
class LayerManagerD3D10 : public LayerManager {
|
|
||||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
|
||||||
typedef mozilla::gfx::IntSize IntSize;
|
|
||||||
typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
|
|
||||||
|
|
||||||
public:
|
|
||||||
LayerManagerD3D10(nsIWidget *aWidget);
|
|
||||||
virtual ~LayerManagerD3D10();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initializes the layer manager, this is when the layer manager will
|
|
||||||
* actually access the device and attempt to create the swap chain used
|
|
||||||
* to draw to the window. If this method fails the device cannot be used.
|
|
||||||
* This function is not threadsafe.
|
|
||||||
*
|
|
||||||
* return True is initialization was succesful, false when it was not.
|
|
||||||
*/
|
|
||||||
bool Initialize(bool force = false, HRESULT* aHresultPtr = nullptr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LayerManager implementation.
|
|
||||||
*/
|
|
||||||
virtual void Destroy();
|
|
||||||
|
|
||||||
virtual void SetRoot(Layer *aLayer);
|
|
||||||
|
|
||||||
virtual void BeginTransaction();
|
|
||||||
|
|
||||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
|
||||||
|
|
||||||
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
|
|
||||||
|
|
||||||
struct CallbackInfo {
|
|
||||||
DrawPaintedLayerCallback Callback;
|
|
||||||
void *CallbackData;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
|
|
||||||
void* aCallbackData,
|
|
||||||
EndTransactionFlags aFlags = END_DEFAULT);
|
|
||||||
|
|
||||||
const CallbackInfo &GetCallbackInfo() { return mCurrentCallbackInfo; }
|
|
||||||
|
|
||||||
// D3D10 guarantees textures can be at least this size
|
|
||||||
enum {
|
|
||||||
MAX_TEXTURE_SIZE = 8192
|
|
||||||
};
|
|
||||||
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize)
|
|
||||||
{
|
|
||||||
return aSize <= gfx::IntSize(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32_t GetMaxTextureSize() const
|
|
||||||
{
|
|
||||||
return MAX_TEXTURE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual already_AddRefed<PaintedLayer> CreatePaintedLayer();
|
|
||||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
|
|
||||||
virtual already_AddRefed<ImageLayer> CreateImageLayer();
|
|
||||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
|
||||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
|
|
||||||
virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer();
|
|
||||||
|
|
||||||
virtual TemporaryRef<DrawTarget>
|
|
||||||
CreateOptimalDrawTarget(const IntSize &aSize,
|
|
||||||
SurfaceFormat aSurfaceFormat);
|
|
||||||
|
|
||||||
virtual TemporaryRef<DrawTarget>
|
|
||||||
CreateOptimalMaskDrawTarget(const IntSize &aSize);
|
|
||||||
|
|
||||||
virtual TemporaryRef<mozilla::gfx::DrawTarget>
|
|
||||||
CreateDrawTarget(const gfx::IntSize &aSize,
|
|
||||||
mozilla::gfx::SurfaceFormat aFormat);
|
|
||||||
|
|
||||||
virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_D3D10; }
|
|
||||||
virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); }
|
|
||||||
|
|
||||||
virtual const char* Name() const { return "D3D10"; }
|
|
||||||
|
|
||||||
// Public helpers
|
|
||||||
|
|
||||||
ID3D10Device1 *device() const { return mDevice; }
|
|
||||||
|
|
||||||
ID3D10Effect *effect() const { return mEffect; }
|
|
||||||
IDXGISwapChain *SwapChain() const
|
|
||||||
{
|
|
||||||
return mSwapChain;
|
|
||||||
}
|
|
||||||
ReadbackManagerD3D10 *readbackManager();
|
|
||||||
|
|
||||||
void SetupInputAssembler();
|
|
||||||
void SetViewport(const nsIntSize &aViewport);
|
|
||||||
const nsIntSize &GetViewport() { return mViewport; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return pointer to the Nv3DVUtils instance
|
|
||||||
*/
|
|
||||||
Nv3DVUtils *GetNv3DVUtils() { return mNv3DVUtils; }
|
|
||||||
|
|
||||||
static void ReportFailure(const nsACString &aMsg, HRESULT aCode);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void SetupPipeline();
|
|
||||||
void UpdateRenderTarget();
|
|
||||||
void VerifyBufferSize();
|
|
||||||
void EnsureReadbackManager();
|
|
||||||
|
|
||||||
void Render(EndTransactionFlags aFlags);
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Device1> mDevice;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Effect> mEffect;
|
|
||||||
nsRefPtr<ID3D10InputLayout> mInputLayout;
|
|
||||||
nsRefPtr<ID3D10Buffer> mVertexBuffer;
|
|
||||||
nsRefPtr<ReadbackManagerD3D10> mReadbackManager;
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10RenderTargetView> mRTView;
|
|
||||||
|
|
||||||
nsRefPtr<IDXGISwapChain> mSwapChain;
|
|
||||||
|
|
||||||
nsIWidget *mWidget;
|
|
||||||
|
|
||||||
bool mDisableSequenceForNextFrame;
|
|
||||||
|
|
||||||
CallbackInfo mCurrentCallbackInfo;
|
|
||||||
|
|
||||||
nsIntSize mViewport;
|
|
||||||
|
|
||||||
/* Nv3DVUtils instance */
|
|
||||||
nsAutoPtr<Nv3DVUtils> mNv3DVUtils;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Context target, nullptr when drawing directly to our swap chain.
|
|
||||||
*/
|
|
||||||
nsRefPtr<gfxContext> mTarget;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copies the content of our backbuffer to the set transaction target.
|
|
||||||
*/
|
|
||||||
void PaintToTarget();
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General information and tree management for OGL layers.
|
|
||||||
*/
|
|
||||||
class LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LayerD3D10(LayerManagerD3D10 *aManager);
|
|
||||||
|
|
||||||
virtual LayerD3D10 *GetFirstChildD3D10() { return nullptr; }
|
|
||||||
|
|
||||||
void SetFirstChild(LayerD3D10 *aParent);
|
|
||||||
|
|
||||||
virtual Layer* GetLayer() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will render a child layer to whatever render target is currently
|
|
||||||
* active.
|
|
||||||
*/
|
|
||||||
virtual void RenderLayer() = 0;
|
|
||||||
virtual void Validate() {}
|
|
||||||
|
|
||||||
ID3D10Device1 *device() const { return mD3DManager->device(); }
|
|
||||||
ID3D10Effect *effect() const { return mD3DManager->effect(); }
|
|
||||||
|
|
||||||
/* Called by the layer manager when it's destroyed */
|
|
||||||
virtual void LayerManagerDestroyed() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return pointer to the Nv3DVUtils instance. Calls equivalent method in LayerManager.
|
|
||||||
*/
|
|
||||||
Nv3DVUtils *GetNv3DVUtils() { return mD3DManager->GetNv3DVUtils(); }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a shader resource view of a texture containing the contents of this
|
|
||||||
* layer. Will try to return an existing texture if possible, or a temporary
|
|
||||||
* one if not. It is the callee's responsibility to release the shader
|
|
||||||
* resource view. Will return null if a texture could not be constructed.
|
|
||||||
* The texture will not be transformed, i.e., it will be in the same coord
|
|
||||||
* space as this.
|
|
||||||
* Any layer that can be used as a mask layer should override this method.
|
|
||||||
* If aSize is non-null, it will contain the size of the texture.
|
|
||||||
*/
|
|
||||||
virtual already_AddRefed<ID3D10ShaderResourceView> GetAsTexture(gfx::IntSize* aSize)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetEffectTransformAndOpacity()
|
|
||||||
{
|
|
||||||
Layer* layer = GetLayer();
|
|
||||||
const gfx::Matrix4x4& transform = layer->GetEffectiveTransform();
|
|
||||||
void* raw = &const_cast<gfx::Matrix4x4&>(transform)._11;
|
|
||||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
|
|
||||||
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(layer->GetEffectiveOpacity());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/*
|
|
||||||
* Finds a texture for this layer's mask layer (if it has one) and sets it
|
|
||||||
* as an input to the shaders.
|
|
||||||
* Returns SHADER_MASK if a texture is loaded, SHADER_NO_MASK if there was no
|
|
||||||
* mask layer, or a texture for the mask layer could not be loaded.
|
|
||||||
*/
|
|
||||||
uint8_t LoadMaskTexture();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select a shader technique using a combination of the following flags.
|
|
||||||
* Not all combinations of flags are supported, and might cause an error,
|
|
||||||
* check the fx file to see which shaders exist. In particular, aFlags should
|
|
||||||
* include any combination of the 0x20 bit = 0 flags OR one of the 0x20 bit = 1
|
|
||||||
* flags. Mask flags can be used in either case.
|
|
||||||
*/
|
|
||||||
ID3D10EffectTechnique* SelectShader(uint8_t aFlags);
|
|
||||||
const static uint8_t SHADER_NO_MASK = 0;
|
|
||||||
const static uint8_t SHADER_MASK = 0x1;
|
|
||||||
const static uint8_t SHADER_MASK_3D = 0x2;
|
|
||||||
// 0x20 bit = 0
|
|
||||||
const static uint8_t SHADER_RGB = 0;
|
|
||||||
const static uint8_t SHADER_RGBA = 0x4;
|
|
||||||
const static uint8_t SHADER_NON_PREMUL = 0;
|
|
||||||
const static uint8_t SHADER_PREMUL = 0x8;
|
|
||||||
const static uint8_t SHADER_LINEAR = 0;
|
|
||||||
const static uint8_t SHADER_POINT = 0x10;
|
|
||||||
// 0x20 bit = 1
|
|
||||||
const static uint8_t SHADER_YCBCR = 0x20;
|
|
||||||
const static uint8_t SHADER_COMPONENT_ALPHA = 0x24;
|
|
||||||
const static uint8_t SHADER_SOLID = 0x28;
|
|
||||||
|
|
||||||
LayerManagerD3D10 *mD3DManager;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
|
|
||||||
#endif /* GFX_LAYERMANAGERD3D9_H */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,478 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "mozilla/layers/PLayerTransaction.h"
|
|
||||||
|
|
||||||
// This must occur *after* layers/PLayerTransaction.h to avoid
|
|
||||||
// typedefs conflicts.
|
|
||||||
#include "mozilla/ArrayUtils.h"
|
|
||||||
|
|
||||||
#include "PaintedLayerD3D10.h"
|
|
||||||
#include "gfxPlatform.h"
|
|
||||||
|
|
||||||
#include "gfxWindowsPlatform.h"
|
|
||||||
#ifdef CAIRO_HAS_D2D_SURFACE
|
|
||||||
#include "gfxD2DSurface.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../d3d9/Nv3DVUtils.h"
|
|
||||||
#include "gfxTeeSurface.h"
|
|
||||||
#include "gfxUtils.h"
|
|
||||||
#include "ReadbackLayer.h"
|
|
||||||
#include "ReadbackProcessor.h"
|
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
#include "mozilla/gfx/2D.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
|
||||||
|
|
||||||
PaintedLayerD3D10::PaintedLayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: PaintedLayer(aManager, nullptr)
|
|
||||||
, LayerD3D10(aManager)
|
|
||||||
, mCurrentSurfaceMode(SurfaceMode::SURFACE_OPAQUE)
|
|
||||||
{
|
|
||||||
mImplData = static_cast<LayerD3D10*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
PaintedLayerD3D10::~PaintedLayerD3D10()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
|
|
||||||
{
|
|
||||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
|
||||||
mInvalidRegion.SimplifyOutward(20);
|
|
||||||
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PaintedLayerD3D10::CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,
|
|
||||||
ID3D10Texture2D* aDest, const nsIntPoint &aDestOffset,
|
|
||||||
const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion)
|
|
||||||
{
|
|
||||||
nsIntRegion retainedRegion;
|
|
||||||
nsIntRegionRectIterator iter(aCopyRegion);
|
|
||||||
const nsIntRect *r;
|
|
||||||
while ((r = iter.Next())) {
|
|
||||||
// Calculate the retained rectangle's position on the old and the new
|
|
||||||
// surface.
|
|
||||||
D3D10_BOX box;
|
|
||||||
box.left = r->x - aSrcOffset.x;
|
|
||||||
box.top = r->y - aSrcOffset.y;
|
|
||||||
box.right = box.left + r->width;
|
|
||||||
box.bottom = box.top + r->height;
|
|
||||||
box.back = 1;
|
|
||||||
box.front = 0;
|
|
||||||
|
|
||||||
device()->CopySubresourceRegion(aDest, 0,
|
|
||||||
r->x - aDestOffset.x,
|
|
||||||
r->y - aDestOffset.y,
|
|
||||||
0,
|
|
||||||
aSrc, 0,
|
|
||||||
&box);
|
|
||||||
|
|
||||||
retainedRegion.Or(retainedRegion, *r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Areas which were valid and were retained are still valid
|
|
||||||
aValidRegion->And(*aValidRegion, retainedRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::RenderLayer()
|
|
||||||
{
|
|
||||||
if (!mTexture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEffectTransformAndOpacity();
|
|
||||||
|
|
||||||
ID3D10EffectTechnique *technique;
|
|
||||||
switch (mCurrentSurfaceMode) {
|
|
||||||
case SurfaceMode::SURFACE_COMPONENT_ALPHA:
|
|
||||||
technique = SelectShader(SHADER_COMPONENT_ALPHA | LoadMaskTexture());
|
|
||||||
break;
|
|
||||||
case SurfaceMode::SURFACE_OPAQUE:
|
|
||||||
technique = SelectShader(SHADER_RGB | SHADER_PREMUL | LoadMaskTexture());
|
|
||||||
break;
|
|
||||||
case SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA:
|
|
||||||
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | LoadMaskTexture());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NS_ERROR("Unknown mode");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIntRegionRectIterator iter(mVisibleRegion);
|
|
||||||
|
|
||||||
const nsIntRect *iterRect;
|
|
||||||
if (mSRView) {
|
|
||||||
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
|
|
||||||
}
|
|
||||||
if (mSRViewOnWhite) {
|
|
||||||
effect()->GetVariableByName("tRGBWhite")->AsShaderResource()->SetResource(mSRViewOnWhite);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((iterRect = iter.Next())) {
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)iterRect->x,
|
|
||||||
(float)iterRect->y,
|
|
||||||
(float)iterRect->width,
|
|
||||||
(float)iterRect->height)
|
|
||||||
);
|
|
||||||
|
|
||||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)(iterRect->x - mTextureRect.x) / (float)mTextureRect.width,
|
|
||||||
(float)(iterRect->y - mTextureRect.y) / (float)mTextureRect.height,
|
|
||||||
(float)iterRect->width / (float)mTextureRect.width,
|
|
||||||
(float)iterRect->height / (float)mTextureRect.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set back to default.
|
|
||||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->
|
|
||||||
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::Validate(ReadbackProcessor *aReadback)
|
|
||||||
{
|
|
||||||
if (mVisibleRegion.IsEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(gfxWindowsPlatform::GetPlatform()->GetD3D10Device()->GetDeviceRemovedReason())) {
|
|
||||||
// Device removed, this will be discovered on the next rendering pass.
|
|
||||||
// Do no validate.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIntRect newTextureRect = mVisibleRegion.GetBounds();
|
|
||||||
|
|
||||||
SurfaceMode mode = GetSurfaceMode();
|
|
||||||
if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA &&
|
|
||||||
(!mParent || !mParent->SupportsComponentAlphaChildren())) {
|
|
||||||
mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
|
|
||||||
}
|
|
||||||
// If we have a transform that requires resampling of our texture, then
|
|
||||||
// we need to make sure we don't sample pixels that haven't been drawn.
|
|
||||||
// We clamp sample coordinates to the texture rect, but when the visible region
|
|
||||||
// doesn't fill the entire texture rect we need to make sure we draw all the
|
|
||||||
// pixels in the texture rect anyway in case they get sampled.
|
|
||||||
nsIntRegion neededRegion = mVisibleRegion;
|
|
||||||
if (!neededRegion.GetBounds().IsEqualInterior(newTextureRect) ||
|
|
||||||
neededRegion.GetNumRects() > 1) {
|
|
||||||
if (MayResample()) {
|
|
||||||
neededRegion = newTextureRect;
|
|
||||||
if (mode == SurfaceMode::SURFACE_OPAQUE) {
|
|
||||||
// We're going to paint outside the visible region, but layout hasn't
|
|
||||||
// promised that it will paint opaquely there, so we'll have to
|
|
||||||
// treat this layer as transparent.
|
|
||||||
mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mCurrentSurfaceMode = mode;
|
|
||||||
|
|
||||||
VerifyContentType(mode);
|
|
||||||
|
|
||||||
nsTArray<ReadbackProcessor::Update> readbackUpdates;
|
|
||||||
nsIntRegion readbackRegion;
|
|
||||||
if (aReadback && UsedForReadback()) {
|
|
||||||
aReadback->GetPaintedLayerUpdates(this, &readbackUpdates, &readbackRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTexture) {
|
|
||||||
if (!mTextureRect.IsEqualInterior(newTextureRect)) {
|
|
||||||
nsRefPtr<ID3D10Texture2D> oldTexture = mTexture;
|
|
||||||
mTexture = nullptr;
|
|
||||||
nsRefPtr<ID3D10Texture2D> oldTextureOnWhite = mTextureOnWhite;
|
|
||||||
mTextureOnWhite = nullptr;
|
|
||||||
|
|
||||||
nsIntRegion retainRegion = mTextureRect;
|
|
||||||
// Old visible region will become the region that is covered by both the
|
|
||||||
// old and the new visible region.
|
|
||||||
retainRegion.And(retainRegion, mVisibleRegion);
|
|
||||||
// No point in retaining parts which were not valid.
|
|
||||||
retainRegion.And(retainRegion, mValidRegion);
|
|
||||||
|
|
||||||
CreateNewTextures(gfx::IntSize(newTextureRect.width, newTextureRect.height), mode);
|
|
||||||
|
|
||||||
nsIntRect largeRect = retainRegion.GetLargestRectangle();
|
|
||||||
|
|
||||||
// If we had no hardware texture before, or have no retained area larger than
|
|
||||||
// the retention threshold, we're not retaining and are done here.
|
|
||||||
// If our texture creation failed this can mean a device reset is pending
|
|
||||||
// and we should silently ignore the failure. In the future when device
|
|
||||||
// failures are properly handled we should test for the type of failure
|
|
||||||
// and gracefully handle different failures. See bug 569081.
|
|
||||||
if (!oldTexture || !mTexture) {
|
|
||||||
mValidRegion.SetEmpty();
|
|
||||||
} else {
|
|
||||||
CopyRegion(oldTexture, mTextureRect.TopLeft(),
|
|
||||||
mTexture, newTextureRect.TopLeft(),
|
|
||||||
retainRegion, &mValidRegion);
|
|
||||||
if (oldTextureOnWhite) {
|
|
||||||
CopyRegion(oldTextureOnWhite, mTextureRect.TopLeft(),
|
|
||||||
mTextureOnWhite, newTextureRect.TopLeft(),
|
|
||||||
retainRegion, &mValidRegion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mTextureRect = newTextureRect;
|
|
||||||
|
|
||||||
if (!mTexture || (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA && !mTextureOnWhite)) {
|
|
||||||
CreateNewTextures(gfx::IntSize(newTextureRect.width, newTextureRect.height), mode);
|
|
||||||
mValidRegion.SetEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIntRegion drawRegion;
|
|
||||||
drawRegion.Sub(neededRegion, mValidRegion);
|
|
||||||
|
|
||||||
if (!drawRegion.IsEmpty()) {
|
|
||||||
LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
|
||||||
if (!cbInfo.Callback) {
|
|
||||||
NS_ERROR("D3D10 should never need to update PaintedLayers in an empty transaction");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawRegion(drawRegion, mode);
|
|
||||||
|
|
||||||
if (readbackUpdates.Length() > 0) {
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
|
||||||
newTextureRect.width, newTextureRect.height,
|
|
||||||
1, 1, 0, D3D10_USAGE_STAGING,
|
|
||||||
D3D10_CPU_ACCESS_READ);
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10Texture2D> readbackTexture;
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(readbackTexture));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("PaintedLayerD3D10::Validate(): Failed to create texture"),
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
device()->CopyResource(readbackTexture, mTexture);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < readbackUpdates.Length(); i++) {
|
|
||||||
mD3DManager->readbackManager()->PostTask(readbackTexture,
|
|
||||||
&readbackUpdates[i],
|
|
||||||
gfxPoint(newTextureRect.x, newTextureRect.y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mValidRegion = neededRegion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::LayerManagerDestroyed()
|
|
||||||
{
|
|
||||||
mD3DManager = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer*
|
|
||||||
PaintedLayerD3D10::GetLayer()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::VerifyContentType(SurfaceMode aMode)
|
|
||||||
{
|
|
||||||
if (mDrawTarget) {
|
|
||||||
SurfaceFormat format = aMode != SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA ?
|
|
||||||
SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
|
|
||||||
|
|
||||||
if (format != mDrawTarget->GetFormat()) {
|
|
||||||
mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, format);
|
|
||||||
|
|
||||||
if (!mDrawTarget) {
|
|
||||||
gfxWarning() << "Failed to create drawtarget for PaintedLayerD3D10.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mValidRegion.SetEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aMode != SurfaceMode::SURFACE_COMPONENT_ALPHA && mTextureOnWhite) {
|
|
||||||
// If we've transitioned away from component alpha, we can delete those resources.
|
|
||||||
mSRViewOnWhite = nullptr;
|
|
||||||
mTextureOnWhite = nullptr;
|
|
||||||
mValidRegion.SetEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::FillTexturesBlackWhite(const nsIntRegion& aRegion, const nsIntPoint& aOffset)
|
|
||||||
{
|
|
||||||
if (mTexture && mTextureOnWhite) {
|
|
||||||
// It would be more optimal to draw the actual geometry, but more code
|
|
||||||
// and probably not worth the win here as this will often be a single
|
|
||||||
// rect.
|
|
||||||
nsRefPtr<ID3D10RenderTargetView> oldRT;
|
|
||||||
device()->OMGetRenderTargets(1, getter_AddRefs(oldRT), nullptr);
|
|
||||||
|
|
||||||
nsRefPtr<ID3D10RenderTargetView> viewBlack;
|
|
||||||
nsRefPtr<ID3D10RenderTargetView> viewWhite;
|
|
||||||
device()->CreateRenderTargetView(mTexture, nullptr, getter_AddRefs(viewBlack));
|
|
||||||
device()->CreateRenderTargetView(mTextureOnWhite, nullptr, getter_AddRefs(viewWhite));
|
|
||||||
|
|
||||||
D3D10_RECT oldScissor;
|
|
||||||
UINT numRects = 1;
|
|
||||||
device()->RSGetScissorRects(&numRects, &oldScissor);
|
|
||||||
|
|
||||||
D3D10_TEXTURE2D_DESC desc;
|
|
||||||
mTexture->GetDesc(&desc);
|
|
||||||
|
|
||||||
D3D10_RECT scissor = { 0, 0, desc.Width, desc.Height };
|
|
||||||
device()->RSSetScissorRects(1, &scissor);
|
|
||||||
|
|
||||||
mD3DManager->SetupInputAssembler();
|
|
||||||
nsIntSize oldVP = mD3DManager->GetViewport();
|
|
||||||
|
|
||||||
mD3DManager->SetViewport(nsIntSize(desc.Width, desc.Height));
|
|
||||||
|
|
||||||
ID3D10RenderTargetView *views[2] = { viewBlack, viewWhite };
|
|
||||||
device()->OMSetRenderTargets(2, views, nullptr);
|
|
||||||
|
|
||||||
gfx3DMatrix transform;
|
|
||||||
transform.Translate(Point3D(-aOffset.x, -aOffset.y, 0));
|
|
||||||
void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
|
|
||||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
|
|
||||||
|
|
||||||
ID3D10EffectTechnique *technique =
|
|
||||||
effect()->GetTechniqueByName("PrepareAlphaExtractionTextures");
|
|
||||||
|
|
||||||
nsIntRegionRectIterator iter(aRegion);
|
|
||||||
|
|
||||||
const nsIntRect *iterRect;
|
|
||||||
while ((iterRect = iter.Next())) {
|
|
||||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
|
||||||
ShaderConstantRectD3D10(
|
|
||||||
(float)iterRect->x,
|
|
||||||
(float)iterRect->y,
|
|
||||||
(float)iterRect->width,
|
|
||||||
(float)iterRect->height)
|
|
||||||
);
|
|
||||||
|
|
||||||
technique->GetPassByIndex(0)->Apply(0);
|
|
||||||
device()->Draw(4, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
views[0] = oldRT;
|
|
||||||
device()->OMSetRenderTargets(1, views, nullptr);
|
|
||||||
mD3DManager->SetViewport(oldVP);
|
|
||||||
device()->RSSetScissorRects(1, &oldScissor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode)
|
|
||||||
{
|
|
||||||
nsIntRect visibleRect = mVisibleRegion.GetBounds();
|
|
||||||
|
|
||||||
if (!mDrawTarget) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
aRegion.SimplifyOutwardByArea(100 * 100);
|
|
||||||
|
|
||||||
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
|
||||||
FillTexturesBlackWhite(aRegion, visibleRect.TopLeft());
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<gfxContext> context = new gfxContext(mDrawTarget);
|
|
||||||
|
|
||||||
context->SetMatrix(
|
|
||||||
context->CurrentMatrix().Translate(-visibleRect.x, -visibleRect.y));
|
|
||||||
if (aMode == SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA) {
|
|
||||||
nsIntRegionRectIterator iter(aRegion);
|
|
||||||
const nsIntRect *iterRect;
|
|
||||||
while ((iterRect = iter.Next())) {
|
|
||||||
mDrawTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mDrawTarget->SetPermitSubpixelAA(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
|
|
||||||
|
|
||||||
LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
|
|
||||||
cbInfo.Callback(this, context, aRegion, DrawRegionClip::DRAW, nsIntRegion(), cbInfo.CallbackData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PaintedLayerD3D10::CreateNewTextures(const gfx::IntSize &aSize, SurfaceMode aMode)
|
|
||||||
{
|
|
||||||
if (aSize.width == 0 || aSize.height == 0) {
|
|
||||||
// Nothing to do.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
|
||||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
|
||||||
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (!mTexture) {
|
|
||||||
hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(mTexture));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create new texture for PaintedLayerD3D10!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRView));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create shader resource view for PaintedLayerD3D10.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mDrawTarget = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA && !mTextureOnWhite) {
|
|
||||||
hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(mTextureOnWhite));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create new texture for PaintedLayerD3D10!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = device()->CreateShaderResourceView(mTextureOnWhite, nullptr, getter_AddRefs(mSRViewOnWhite));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
NS_WARNING("Failed to create shader resource view for PaintedLayerD3D10.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mDrawTarget = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mDrawTarget) {
|
|
||||||
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
|
||||||
mDrawTarget = Factory::CreateDualDrawTargetForD3D10Textures(mTexture, mTextureOnWhite, SurfaceFormat::B8G8R8X8);
|
|
||||||
} else {
|
|
||||||
mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, aMode != SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA ?
|
|
||||||
SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mDrawTarget) {
|
|
||||||
gfxWarning() << "Failed to create DrawTarget for PaintedLayerD3D10.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace layers */
|
|
||||||
} /* namespace mozilla */
|
|
@ -1,73 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_PAINTEDLAYERD3D10_H
|
|
||||||
#define GFX_PAINTEDLAYERD3D10_H
|
|
||||||
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class PaintedLayerD3D10 : public PaintedLayer,
|
|
||||||
public LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PaintedLayerD3D10(LayerManagerD3D10 *aManager);
|
|
||||||
virtual ~PaintedLayerD3D10();
|
|
||||||
|
|
||||||
void Validate(ReadbackProcessor *aReadback);
|
|
||||||
|
|
||||||
/* PaintedLayer implementation */
|
|
||||||
void InvalidateRegion(const nsIntRegion& aRegion);
|
|
||||||
|
|
||||||
/* LayerD3D10 implementation */
|
|
||||||
virtual Layer* GetLayer();
|
|
||||||
virtual void RenderLayer();
|
|
||||||
virtual void Validate() { Validate(nullptr); }
|
|
||||||
virtual void LayerManagerDestroyed();
|
|
||||||
|
|
||||||
private:
|
|
||||||
/* Texture with our surface data */
|
|
||||||
nsRefPtr<ID3D10Texture2D> mTexture;
|
|
||||||
|
|
||||||
/* Shader resource view for our texture */
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mSRView;
|
|
||||||
|
|
||||||
/* Texture for render-on-whitew when doing component alpha */
|
|
||||||
nsRefPtr<ID3D10Texture2D> mTextureOnWhite;
|
|
||||||
|
|
||||||
/* Shader resource view for our render-on-white texture */
|
|
||||||
nsRefPtr<ID3D10ShaderResourceView> mSRViewOnWhite;
|
|
||||||
|
|
||||||
/* Area of layer currently stored in texture(s) */
|
|
||||||
nsIntRect mTextureRect;
|
|
||||||
|
|
||||||
/* Last surface mode set in Validate() */
|
|
||||||
SurfaceMode mCurrentSurfaceMode;
|
|
||||||
|
|
||||||
/* Checks if our D2D surface has the right content type */
|
|
||||||
void VerifyContentType(SurfaceMode aMode);
|
|
||||||
|
|
||||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
|
||||||
|
|
||||||
/* Have a region of our layer drawn */
|
|
||||||
void DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode);
|
|
||||||
|
|
||||||
/* Create a new texture */
|
|
||||||
void CreateNewTextures(const gfx::IntSize &aSize, SurfaceMode aMode);
|
|
||||||
|
|
||||||
// Fill textures with opaque black and white in the specified region.
|
|
||||||
void FillTexturesBlackWhite(const nsIntRegion& aRegion, const nsIntPoint& aOffset);
|
|
||||||
|
|
||||||
/* Copy a texture region */
|
|
||||||
void CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,
|
|
||||||
ID3D10Texture2D* aDest, const nsIntPoint &aDestOffset,
|
|
||||||
const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion);
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
#endif /* GFX_PAINTEDLAYERD3D10_H */
|
|
@ -1,33 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_READBACKLAYERD3D10_H
|
|
||||||
#define GFX_READBACKLAYERD3D10_H
|
|
||||||
|
|
||||||
#include "LayerManagerD3D10.h"
|
|
||||||
#include "ReadbackLayer.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class ReadbackLayerD3D10 :
|
|
||||||
public ReadbackLayer,
|
|
||||||
public LayerD3D10
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ReadbackLayerD3D10(LayerManagerD3D10 *aManager)
|
|
||||||
: ReadbackLayer(aManager, nullptr),
|
|
||||||
LayerD3D10(aManager)
|
|
||||||
{
|
|
||||||
mImplData = static_cast<LayerD3D10*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Layer* GetLayer() { return this; }
|
|
||||||
virtual void RenderLayer() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* layers */
|
|
||||||
} /* mozilla */
|
|
||||||
#endif /* GFX_READBACKLAYERD3D10_H */
|
|
@ -1,225 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "ReadbackManagerD3D10.h"
|
|
||||||
#include "ReadbackProcessor.h"
|
|
||||||
#include "ReadbackLayer.h"
|
|
||||||
|
|
||||||
#include "nsIThread.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "gfxImageSurface.h"
|
|
||||||
#include "gfxContext.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
// Structure that contains the information required to execute a readback task,
|
|
||||||
// the only member accessed off the main thread here is mReadbackTexture. Since
|
|
||||||
// mLayer may be released only on the main thread this object should always be
|
|
||||||
// destroyed on the main thread!
|
|
||||||
struct ReadbackTask {
|
|
||||||
// The texture that we copied the contents of the paintedlayer to.
|
|
||||||
nsRefPtr<ID3D10Texture2D> mReadbackTexture;
|
|
||||||
// This exists purely to keep the ReadbackLayer alive for the lifetime of
|
|
||||||
// mUpdate. Note that this addref and release should occur -solely- on the
|
|
||||||
// main thread.
|
|
||||||
nsRefPtr<ReadbackLayer> mLayer;
|
|
||||||
ReadbackProcessor::Update mUpdate;
|
|
||||||
// The origin in PaintedLayer coordinates of mReadbackTexture.
|
|
||||||
gfxPoint mOrigin;
|
|
||||||
// mLayer->GetBackgroundOffset() when the task is created. We have
|
|
||||||
// to save this in the ReadbackTask because it might change before
|
|
||||||
// the update is delivered to the readback sink.
|
|
||||||
nsIntPoint mBackgroundOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class is created and dispatched from the Readback thread but it must be
|
|
||||||
// destroyed by the main thread.
|
|
||||||
class ReadbackResultWriter MOZ_FINAL : public nsIRunnable
|
|
||||||
{
|
|
||||||
~ReadbackResultWriter() {}
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
public:
|
|
||||||
ReadbackResultWriter(ReadbackTask *aTask) : mTask(aTask) {}
|
|
||||||
|
|
||||||
NS_IMETHODIMP Run()
|
|
||||||
{
|
|
||||||
ReadbackProcessor::Update *update = &mTask->mUpdate;
|
|
||||||
|
|
||||||
if (!update->mLayer->GetSink()) {
|
|
||||||
// This can happen when a plugin is destroyed.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIntPoint offset = mTask->mBackgroundOffset;
|
|
||||||
|
|
||||||
D3D10_TEXTURE2D_DESC desc;
|
|
||||||
mTask->mReadbackTexture->GetDesc(&desc);
|
|
||||||
|
|
||||||
D3D10_MAPPED_TEXTURE2D mappedTex;
|
|
||||||
// We know this map will immediately succeed, as we've already mapped this
|
|
||||||
// copied data on our task thread.
|
|
||||||
HRESULT hr = mTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
// If this fails we're never going to get our PaintedLayer content.
|
|
||||||
update->mLayer->GetSink()->SetUnknown(update->mSequenceCounter);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> sourceSurface =
|
|
||||||
new gfxImageSurface((unsigned char*)mappedTex.pData,
|
|
||||||
gfxIntSize(desc.Width, desc.Height),
|
|
||||||
mappedTex.RowPitch,
|
|
||||||
gfxImageFormat::RGB24);
|
|
||||||
|
|
||||||
nsRefPtr<gfxContext> ctx =
|
|
||||||
update->mLayer->GetSink()->BeginUpdate(update->mUpdateRect + offset,
|
|
||||||
update->mSequenceCounter);
|
|
||||||
|
|
||||||
if (ctx) {
|
|
||||||
ctx->SetMatrix(
|
|
||||||
ctx->CurrentMatrix().Translate(offset.x, offset.y));
|
|
||||||
ctx->SetSource(sourceSurface, gfxPoint(mTask->mOrigin.x,
|
|
||||||
mTask->mOrigin.y));
|
|
||||||
ctx->Paint();
|
|
||||||
|
|
||||||
update->mLayer->GetSink()->EndUpdate(ctx, update->mUpdateRect + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
mTask->mReadbackTexture->Unmap(0);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsAutoPtr<ReadbackTask> mTask;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(ReadbackResultWriter, nsIRunnable)
|
|
||||||
|
|
||||||
DWORD WINAPI StartTaskThread(void *aManager)
|
|
||||||
{
|
|
||||||
static_cast<ReadbackManagerD3D10*>(aManager)->ProcessTasks();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadbackManagerD3D10::ReadbackManagerD3D10()
|
|
||||||
: mRefCnt(0)
|
|
||||||
{
|
|
||||||
::InitializeCriticalSection(&mTaskMutex);
|
|
||||||
mShutdownEvent = ::CreateEventA(nullptr, FALSE, FALSE, nullptr);
|
|
||||||
mTaskSemaphore = ::CreateSemaphoreA(nullptr, 0, 1000000, nullptr);
|
|
||||||
mTaskThread = ::CreateThread(nullptr, 0, StartTaskThread, this, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadbackManagerD3D10::~ReadbackManagerD3D10()
|
|
||||||
{
|
|
||||||
::SetEvent(mShutdownEvent);
|
|
||||||
|
|
||||||
// This shouldn't take longer than 5 seconds, if it does we're going to choose
|
|
||||||
// to leak the thread and its synchronisation in favor of crashing or freezing
|
|
||||||
DWORD result = ::WaitForSingleObject(mTaskThread, 5000);
|
|
||||||
if (result != WAIT_TIMEOUT) {
|
|
||||||
::DeleteCriticalSection(&mTaskMutex);
|
|
||||||
::CloseHandle(mShutdownEvent);
|
|
||||||
::CloseHandle(mTaskSemaphore);
|
|
||||||
::CloseHandle(mTaskThread);
|
|
||||||
} else {
|
|
||||||
NS_RUNTIMEABORT("ReadbackManager: Task thread did not shutdown in 5 seconds.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReadbackManagerD3D10::PostTask(ID3D10Texture2D *aTexture, void *aUpdate, const gfxPoint &aOrigin)
|
|
||||||
{
|
|
||||||
ReadbackTask *task = new ReadbackTask;
|
|
||||||
task->mReadbackTexture = aTexture;
|
|
||||||
task->mUpdate = *static_cast<ReadbackProcessor::Update*>(aUpdate);
|
|
||||||
task->mOrigin = aOrigin;
|
|
||||||
task->mLayer = task->mUpdate.mLayer;
|
|
||||||
task->mBackgroundOffset = task->mLayer->GetBackgroundLayerOffset();
|
|
||||||
|
|
||||||
::EnterCriticalSection(&mTaskMutex);
|
|
||||||
mPendingReadbackTasks.AppendElement(task);
|
|
||||||
::LeaveCriticalSection(&mTaskMutex);
|
|
||||||
|
|
||||||
::ReleaseSemaphore(mTaskSemaphore, 1, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
ReadbackManagerD3D10::QueryInterface(REFIID riid, void **ppvObject)
|
|
||||||
{
|
|
||||||
if (!ppvObject) {
|
|
||||||
return E_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (riid == IID_IUnknown) {
|
|
||||||
*ppvObject = this;
|
|
||||||
} else {
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
ReadbackManagerD3D10::AddRef()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(),
|
|
||||||
"ReadbackManagerD3D10 should only be refcounted on main thread.");
|
|
||||||
return ++mRefCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
ReadbackManagerD3D10::Release()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(),
|
|
||||||
"ReadbackManagerD3D10 should only be refcounted on main thread.");
|
|
||||||
ULONG newRefCnt = --mRefCnt;
|
|
||||||
if (!newRefCnt) {
|
|
||||||
mRefCnt++;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
return newRefCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReadbackManagerD3D10::ProcessTasks()
|
|
||||||
{
|
|
||||||
HANDLE handles[] = { mTaskSemaphore, mShutdownEvent };
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
|
||||||
if (result != WAIT_OBJECT_0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
::EnterCriticalSection(&mTaskMutex);
|
|
||||||
if (mPendingReadbackTasks.Length() == 0) {
|
|
||||||
NS_RUNTIMEABORT("Trying to read from an empty array, bad bad bad");
|
|
||||||
}
|
|
||||||
ReadbackTask *nextReadbackTask = mPendingReadbackTasks[0].forget();
|
|
||||||
mPendingReadbackTasks.RemoveElementAt(0);
|
|
||||||
::LeaveCriticalSection(&mTaskMutex);
|
|
||||||
|
|
||||||
// We want to block here until the texture contents are available, the
|
|
||||||
// easiest thing is to simply map and unmap.
|
|
||||||
D3D10_MAPPED_TEXTURE2D mappedTex;
|
|
||||||
nextReadbackTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
|
|
||||||
nextReadbackTask->mReadbackTexture->Unmap(0);
|
|
||||||
|
|
||||||
// We can only send the update to the sink on the main thread, so post an
|
|
||||||
// event there to do so. Ownership of the task is passed from
|
|
||||||
// mPendingReadbackTasks to ReadbackResultWriter here.
|
|
||||||
nsCOMPtr<nsIThread> thread = do_GetMainThread();
|
|
||||||
thread->Dispatch(new ReadbackResultWriter(nextReadbackTask),
|
|
||||||
nsIEventTarget::DISPATCH_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef GFX_READBACKMANAGERD3D10_H
|
|
||||||
#define GFX_READBACKMANAGERD3D10_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <d3d10_1.h>
|
|
||||||
|
|
||||||
#include "nsTArray.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "gfxPoint.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
DWORD WINAPI StartTaskThread(void *aManager);
|
|
||||||
|
|
||||||
struct ReadbackTask;
|
|
||||||
|
|
||||||
class ReadbackManagerD3D10 MOZ_FINAL : public IUnknown
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ReadbackManagerD3D10();
|
|
||||||
~ReadbackManagerD3D10();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell the readback manager to post a readback task.
|
|
||||||
*
|
|
||||||
* @param aTexture D3D10_USAGE_STAGING texture that will contain the data that
|
|
||||||
* was readback.
|
|
||||||
* @param aUpdate ReadbackProcessor::Update object. This is a void pointer
|
|
||||||
* since we cannot forward declare a nested class, and do not
|
|
||||||
* export ReadbackProcessor.h
|
|
||||||
* @param aOrigin Origin of the aTexture surface in the PaintedLayer
|
|
||||||
* coordinate system.
|
|
||||||
*/
|
|
||||||
void PostTask(ID3D10Texture2D *aTexture, void *aUpdate, const gfxPoint &aOrigin);
|
|
||||||
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
|
|
||||||
void **ppvObject);
|
|
||||||
virtual ULONG STDMETHODCALLTYPE AddRef(void);
|
|
||||||
virtual ULONG STDMETHODCALLTYPE Release(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend DWORD WINAPI StartTaskThread(void *aManager);
|
|
||||||
|
|
||||||
void ProcessTasks();
|
|
||||||
|
|
||||||
// The invariant maintained by |mTaskSemaphore| is that the readback thread
|
|
||||||
// will awaken from WaitForMultipleObjects() at least once per readback
|
|
||||||
// task enqueued by the main thread. Since the readback thread processes
|
|
||||||
// exactly one task per wakeup (with one exception), no tasks are lost. The
|
|
||||||
// exception is when the readback thread is shut down, which orphans the
|
|
||||||
// remaining tasks, on purpose.
|
|
||||||
HANDLE mTaskSemaphore;
|
|
||||||
// Event signaled when the task thread should shutdown
|
|
||||||
HANDLE mShutdownEvent;
|
|
||||||
// Handle to the task thread
|
|
||||||
HANDLE mTaskThread;
|
|
||||||
|
|
||||||
// FiFo list of readback tasks that are to be executed. Access is synchronized
|
|
||||||
// by mTaskMutex.
|
|
||||||
CRITICAL_SECTION mTaskMutex;
|
|
||||||
nsTArray<nsAutoPtr<ReadbackTask>> mPendingReadbackTasks;
|
|
||||||
|
|
||||||
ULONG mRefCnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GFX_READBACKMANAGERD3D10_H */
|
|
@ -1,5 +0,0 @@
|
|||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
fxc LayerManagerD3D10.fx -nologo -FhLayerManagerD3D10Effect.h -Tfx_4_0
|
|
@ -13,10 +13,6 @@
|
|||||||
#include "SurfaceTypes.h"
|
#include "SurfaceTypes.h"
|
||||||
#include "mozilla/WidgetUtils.h"
|
#include "mozilla/WidgetUtils.h"
|
||||||
|
|
||||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
|
||||||
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
#define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
#define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* vim: sw=2 ts=8 et :
|
|
||||||
*/
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include <d3d10_1.h>
|
|
||||||
#include <dxgi.h>
|
|
||||||
|
|
||||||
#include "mozilla/gfx/Point.h"
|
|
||||||
#include "mozilla/layers/LayerManagerComposite.h"
|
|
||||||
#include "mozilla/layers/PLayerTransaction.h"
|
|
||||||
#include "ShadowLayers.h"
|
|
||||||
|
|
||||||
using namespace mozilla::gl;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
|
|
||||||
/*static*/ void
|
|
||||||
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/ bool
|
|
||||||
LayerManagerComposite::SupportsDirectTexturing()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/ void
|
|
||||||
LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GetDescriptor(ID3D10Texture2D* aTexture, SurfaceDescriptorD3D10* aDescr)
|
|
||||||
{
|
|
||||||
NS_ABORT_IF_FALSE(aTexture && aDescr, "Params must be nonnull");
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
IDXGIResource* dr = nullptr;
|
|
||||||
hr = aTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&dr);
|
|
||||||
if (!SUCCEEDED(hr) || !dr)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
hr = dr->GetSharedHandle(reinterpret_cast<HANDLE*>(&aDescr->handle()));
|
|
||||||
return !!SUCCEEDED(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ID3D10Texture2D>
|
|
||||||
OpenForeign(ID3D10Device* aDevice, const SurfaceDescriptorD3D10& aDescr)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
ID3D10Texture2D* tex = nullptr;
|
|
||||||
hr = aDevice->OpenSharedResource(reinterpret_cast<HANDLE>(aDescr.handle()),
|
|
||||||
__uuidof(ID3D10Texture2D),
|
|
||||||
(void**)&tex);
|
|
||||||
if (!SUCCEEDED(hr) || !tex)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return nsRefPtr<ID3D10Texture2D>(tex).forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace layers
|
|
||||||
} // namespace mozilla
|
|
@ -1,34 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
||||||
* vim: sw=2 ts=8 et :
|
|
||||||
*/
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_layers_ShadowLayerUtilsD3D10_h
|
|
||||||
#define mozilla_layers_ShadowLayerUtilsD3D10_h
|
|
||||||
|
|
||||||
#define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
|
||||||
|
|
||||||
struct ID3D10Device;
|
|
||||||
struct ID3D10Texture2D;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class SurfaceDescriptorD3D10;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write into |aDescr| a cross-process descriptor of |aTexture|, if
|
|
||||||
* possible. Return true iff |aDescr| was successfully set.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
GetDescriptor(ID3D10Texture2D* aTexture, SurfaceDescriptorD3D10* aDescr);
|
|
||||||
|
|
||||||
already_AddRefed<ID3D10Texture2D>
|
|
||||||
OpenForeign(ID3D10Device* aDevice, const SurfaceDescriptorD3D10& aDescr);
|
|
||||||
|
|
||||||
} // namespace layers
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif // mozilla_layers_ShadowLayerUtilsD3D10_h
|
|
@ -66,26 +66,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||||||
'd3d9/Nv3DVUtils.cpp',
|
'd3d9/Nv3DVUtils.cpp',
|
||||||
]
|
]
|
||||||
if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
|
||||||
EXPORTS += [
|
|
||||||
'd3d10/LayerManagerD3D10.h',
|
|
||||||
'd3d10/ReadbackManagerD3D10.h',
|
|
||||||
]
|
|
||||||
EXPORTS.mozilla.layers += [
|
EXPORTS.mozilla.layers += [
|
||||||
'd3d11/CompositorD3D11.h',
|
'd3d11/CompositorD3D11.h',
|
||||||
'd3d11/ReadbackManagerD3D11.h',
|
'd3d11/ReadbackManagerD3D11.h',
|
||||||
'd3d11/TextureD3D11.h',
|
'd3d11/TextureD3D11.h',
|
||||||
'ipc/ShadowLayerUtilsD3D10.h',
|
|
||||||
]
|
]
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'd3d10/CanvasLayerD3D10.cpp',
|
|
||||||
'd3d10/ColorLayerD3D10.cpp',
|
|
||||||
'd3d10/ContainerLayerD3D10.cpp',
|
|
||||||
'd3d10/ImageLayerD3D10.cpp',
|
|
||||||
'd3d10/LayerManagerD3D10.cpp',
|
|
||||||
'd3d10/PaintedLayerD3D10.cpp',
|
|
||||||
'd3d10/ReadbackManagerD3D10.cpp',
|
|
||||||
'd3d11/TextureD3D11.cpp',
|
'd3d11/TextureD3D11.cpp',
|
||||||
'ipc/ShadowLayerUtilsD3D10.cpp',
|
|
||||||
]
|
]
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'd3d11/CompositorD3D11.cpp',
|
'd3d11/CompositorD3D11.cpp',
|
||||||
|
Loading…
Reference in New Issue
Block a user