Bug 1167235 - Part 1 - Render canvas2D into TextureClient directly. r=Bas

This commit is contained in:
Nicolas Silva 2016-07-01 10:58:06 +02:00
Родитель 30cae3d32d
Коммит 55982c743c
12 изменённых файлов: 467 добавлений и 52 удалений

Просмотреть файл

@ -85,6 +85,7 @@
#include "mozilla/EndianUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Helpers.h"
#include "mozilla/gfx/Tools.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "mozilla/gfx/PatternHelpers.h"
@ -120,6 +121,7 @@
#include "CanvasUtils.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "mozilla/layers/CanvasClient.h"
#undef free // apparently defined by some windows header, clashing with a free()
// method in SkTypes.h
@ -223,10 +225,32 @@ protected:
Point mEnd;
};
bool
CanvasRenderingContext2D::PatternIsOpaque(CanvasRenderingContext2D::Style aStyle) const
{
const ContextState& state = CurrentState();
if (state.globalAlpha < 1.0) {
return false;
}
if (state.patternStyles[aStyle] && state.patternStyles[aStyle]->mSurface) {
return IsOpaqueFormat(state.patternStyles[aStyle]->mSurface->GetFormat());
}
// TODO: for gradient patterns we could check that all stops are opaque
// colors.
if (!state.gradientStyles[aStyle]) {
// it's a color pattern.
return Color::FromABGR(state.colorStyles[aStyle]).a >= 1.0;
}
return false;
}
// This class is named 'GeneralCanvasPattern' instead of just
// 'GeneralPattern' to keep Windows PGO builds from confusing the
// GeneralPattern class in gfxContext.cpp with this one.
class CanvasGeneralPattern
{
public:
@ -1276,6 +1300,8 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
RefPtr<SourceSurface> snapshot;
Matrix transform;
RefPtr<PersistentBufferProvider> oldBufferProvider = mBufferProvider;
AutoReturnSnapshot autoReturn(nullptr);
if (mTarget) {
snapshot = mTarget->Snapshot();
@ -1285,14 +1311,16 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
// When mBufferProvider is true but we have no mTarget, our current state's
// transform is always valid. See ReturnTarget().
transform = CurrentState().transform;
snapshot = mBufferProvider->GetSnapshot();
snapshot = mBufferProvider->BorrowSnapshot();
autoReturn.mBufferProvider = mBufferProvider;
autoReturn.mSnapshot = &snapshot;
}
mTarget = nullptr;
mBufferProvider = nullptr;
mResetLayer = true;
// Recreate target using the new rendering mode
RenderingMode attemptedMode = EnsureTarget(aRenderingMode);
RenderingMode attemptedMode = EnsureTarget(nullptr, aRenderingMode);
if (!IsTargetValid())
return false;
@ -1425,7 +1453,8 @@ CanvasRenderingContext2D::CheckSizeForSkiaGL(IntSize aSize) {
}
CanvasRenderingContext2D::RenderingMode
CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
RenderingMode aRenderingMode)
{
// This would make no sense, so make sure we don't get ourselves in a mess
MOZ_ASSERT(mRenderingMode != RenderingMode::DefaultBackendMode);
@ -1437,8 +1466,21 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
}
if (mBufferProvider && mode == mRenderingMode) {
mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
gfx::Rect rect(0, 0, mWidth, mHeight);
if (aCoveredRect && CurrentState().transform.TransformBounds(*aCoveredRect).Contains(rect)) {
mTarget = mBufferProvider->BorrowDrawTarget(IntRect());
} else {
mTarget = mBufferProvider->BorrowDrawTarget(IntRect(0, 0, mWidth, mHeight));
}
if (mTarget) {
// Restore clip and transform.
mTarget->SetTransform(CurrentState().transform);
for (uint32_t i = 0; i < mStyleStack.Length(); i++) {
for (uint32_t c = 0; c < mStyleStack[i].clipsPushed.Length(); c++) {
mTarget->PushClip(mStyleStack[i].clipsPushed[c]);
}
}
return mRenderingMode;
} else {
mBufferProvider = nullptr;
@ -1495,7 +1537,7 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
}
if (mBufferProvider) {
mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
mTarget = mBufferProvider->BorrowDrawTarget(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
} else if (!mTarget) {
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
mode = RenderingMode::SoftwareBackendMode;
@ -1623,7 +1665,12 @@ CanvasRenderingContext2D::ReturnTarget()
{
if (mTarget && mBufferProvider) {
CurrentState().transform = mTarget->GetTransform();
mBufferProvider->ReturnAndUseDT(mTarget.forget());
for (uint32_t i = 0; i < mStyleStack.Length(); i++) {
for (uint32_t c = 0; c < mStyleStack[i].clipsPushed.Length(); c++) {
mTarget->PopClip();
}
}
mBufferProvider->ReturnDrawTarget(mTarget.forget());
}
}
@ -2598,9 +2645,11 @@ CanvasRenderingContext2D::ClearRect(double aX, double aY, double aW,
return;
}
EnsureTarget();
gfx::Rect clearRect(aX, aY, aW, aH);
mTarget->ClearRect(gfx::Rect(aX, aY, aW, aH));
EnsureTarget(&clearRect);
mTarget->ClearRect(clearRect);
RedrawUser(gfxRect(aX, aY, aW, aH));
}
@ -2661,18 +2710,22 @@ CanvasRenderingContext2D::FillRect(double aX, double aY, double aW,
}
}
gfx::Rect bounds;
CompositionOp op = UsedOperation();
bool discardContent = PatternIsOpaque(Style::FILL)
&& (op == CompositionOp::OP_OVER || op == CompositionOp::OP_DEST_OUT);
EnsureTarget();
const gfx::Rect fillRect(aX, aY, aW, aH);
EnsureTarget(discardContent ? &fillRect : nullptr);
gfx::Rect bounds;
if (NeedToCalculateBounds()) {
bounds = gfx::Rect(aX, aY, aW, aH);
bounds = mTarget->GetTransform().TransformBounds(bounds);
bounds = mTarget->GetTransform().TransformBounds(fillRect);
}
AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)->
FillRect(gfx::Rect(aX, aY, aW, aH),
CanvasGeneralPattern().ForStyle(this, Style::FILL, mTarget),
DrawOptions(state.globalAlpha, UsedOperation()));
DrawOptions(state.globalAlpha, op));
RedrawUser(gfxRect(aX, aY, aW, aH));
}
@ -5646,7 +5699,14 @@ CanvasRenderingContext2D::GetBufferProvider(LayerManager* aManager)
return nullptr;
}
if (aManager) {
mBufferProvider = aManager->CreatePersistentBufferProvider(gfx::IntSize(mWidth, mHeight),
GetSurfaceFormat());
}
if (!mBufferProvider) {
mBufferProvider = new PersistentBufferProviderBasic(mTarget);
}
return mBufferProvider;
}

Просмотреть файл

@ -635,7 +635,8 @@ protected:
*
* Returns the actual rendering mode being used by the created target.
*/
RenderingMode EnsureTarget(RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
RenderingMode EnsureTarget(const gfx::Rect* aCoveredRect = nullptr,
RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
/**
* Disposes an old target and prepares to lazily create a new target.
@ -661,6 +662,12 @@ protected:
*/
mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
/**
* Returns true if we know for sure that the pattern for a given style is opaque.
* Usefull to know if we can discard the content below in certain situations.
*/
bool PatternIsOpaque(Style aStyle) const;
/**
* Update CurrentState().filter with the filter description for
* CurrentState().filterChain.

Просмотреть файл

@ -98,6 +98,22 @@ BytesPerPixel(SurfaceFormat aFormat)
}
}
static inline bool
IsOpaqueFormat(SurfaceFormat aFormat) {
switch (aFormat) {
case SurfaceFormat::B8G8R8X8:
case SurfaceFormat::R8G8B8X8:
case SurfaceFormat::X8R8G8B8:
case SurfaceFormat::YUV:
case SurfaceFormat::NV12:
case SurfaceFormat::YUV422:
case SurfaceFormat::R5G6B5_UINT16:
return true;
default:
return false;
}
}
template<typename T, int alignment = 16>
struct AlignedArray
{

Просмотреть файл

@ -85,10 +85,21 @@ CopyableCanvasLayer::IsDataValid(const Data& aData)
void
CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
{
AutoReturnSnapshot autoReturn;
if (mAsyncRenderer) {
mSurface = mAsyncRenderer->GetSurface();
} else if (!mGLFrontbuffer && mBufferProvider) {
mSurface = mBufferProvider->GetSnapshot();
mSurface = mBufferProvider->BorrowSnapshot();
if (aDestTarget) {
// If !aDestTarget we'll end up painting using mSurface later,
// so we can't return it to the provider (note that this will trigger a
// copy of the snapshot behind the scenes when the provider is unlocked).
autoReturn.mSnapshot = &mSurface;
}
// Either way we need to call ReturnSnapshot because ther may be an
// underlying TextureClient that has to be unlocked.
autoReturn.mBufferProvider = mBufferProvider;
}
if (!mGLContext && aDestTarget) {
@ -99,6 +110,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
IntPoint(0, 0));
mSurface = nullptr;
}
return;
}

Просмотреть файл

@ -177,19 +177,14 @@ LayerManager::CreatePersistentBufferProvider(const mozilla::gfx::IntSize &aSize,
mozilla::gfx::SurfaceFormat aFormat)
{
RefPtr<PersistentBufferProviderBasic> bufferProvider =
new PersistentBufferProviderBasic(aSize, aFormat,
PersistentBufferProviderBasic::Create(aSize, aFormat,
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
if (!bufferProvider->IsValid()) {
bufferProvider =
new PersistentBufferProviderBasic(aSize, aFormat,
if (!bufferProvider) {
bufferProvider = PersistentBufferProviderBasic::Create(aSize, aFormat,
gfxPlatform::GetPlatform()->GetFallbackCanvasBackend());
}
if (!bufferProvider->IsValid()) {
return nullptr;
}
return bufferProvider.forget();
}

Просмотреть файл

@ -16,10 +16,215 @@ using namespace gfx;
namespace layers {
PersistentBufferProviderBasic::PersistentBufferProviderBasic(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
PersistentBufferProviderBasic::PersistentBufferProviderBasic(DrawTarget* aDt)
: mDrawTarget(aDt)
{
MOZ_COUNT_CTOR(PersistentBufferProviderBasic);
}
PersistentBufferProviderBasic::~PersistentBufferProviderBasic()
{
MOZ_COUNT_DTOR(PersistentBufferProviderBasic);
}
already_AddRefed<gfx::DrawTarget>
PersistentBufferProviderBasic::BorrowDrawTarget(const gfx::IntRect& aPersistedRect)
{
MOZ_ASSERT(!mSnapshot);
RefPtr<gfx::DrawTarget> dt(mDrawTarget);
return dt.forget();
}
bool
PersistentBufferProviderBasic::ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT)
{
RefPtr<gfx::DrawTarget> dt(aDT);
MOZ_ASSERT(mDrawTarget == dt);
return true;
}
already_AddRefed<gfx::SourceSurface>
PersistentBufferProviderBasic::BorrowSnapshot()
{
mSnapshot = mDrawTarget->Snapshot();
RefPtr<SourceSurface> snapshot = mSnapshot;
return snapshot.forget();
}
void
PersistentBufferProviderBasic::ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot)
{
RefPtr<SourceSurface> snapshot = aSnapshot;
MOZ_ASSERT(!snapshot || snapshot == mSnapshot);
mSnapshot = nullptr;
}
//static
already_AddRefed<PersistentBufferProviderBasic>
PersistentBufferProviderBasic::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aBackend)
{
mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(aBackend, aSize, aFormat);
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(aBackend, aSize, aFormat);
if (!dt) {
return nullptr;
}
RefPtr<PersistentBufferProviderBasic> provider =
new PersistentBufferProviderBasic(dt);
return provider.forget();
}
//static
already_AddRefed<PersistentBufferProviderShared>
PersistentBufferProviderShared::Create(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
CompositableForwarder* aFwd)
{
if (!aFwd || !aFwd->IPCOpen()) {
return nullptr;
}
RefPtr<TextureClient> texture = TextureClient::CreateForDrawing(
aFwd, aFormat, aSize,
BackendSelector::Canvas,
TextureFlags::IMMEDIATE_UPLOAD,
TextureAllocationFlags::ALLOC_DEFAULT
);
if (!texture) {
return nullptr;
}
RefPtr<PersistentBufferProviderShared> provider =
new PersistentBufferProviderShared(aSize, aFormat, aFwd, texture);
return provider.forget();
}
PersistentBufferProviderShared::PersistentBufferProviderShared(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
CompositableForwarder* aFwd,
RefPtr<TextureClient>& aTexture)
: mSize(aSize)
, mFormat(aFormat)
, mFwd(aFwd)
, mBack(aTexture.forget())
{
MOZ_COUNT_CTOR(PersistentBufferProviderShared);
}
PersistentBufferProviderShared::~PersistentBufferProviderShared()
{
MOZ_COUNT_DTOR(PersistentBufferProviderShared);
mDrawTarget = nullptr;
if (mBack && mBack->IsLocked()) {
mBack->Unlock();
}
if (mFront && mFront->IsLocked()) {
mFront->Unlock();
}
}
already_AddRefed<gfx::DrawTarget>
PersistentBufferProviderShared::BorrowDrawTarget(const gfx::IntRect& aPersistedRect)
{
if (!mFwd->IPCOpen()) {
return nullptr;
}
if (!mDrawTarget) {
if (!mBack) {
mBack = TextureClient::CreateForDrawing(
mFwd, mFormat, mSize,
BackendSelector::Canvas,
TextureFlags::IMMEDIATE_UPLOAD,
TextureAllocationFlags::ALLOC_DEFAULT
);
}
if (!mBack) {
return nullptr;
}
if (!mBack->Lock(OpenMode::OPEN_READ_WRITE)) {
return nullptr;
}
if (!aPersistedRect.IsEmpty() && mFront
&& mFront->Lock(OpenMode::OPEN_READ)) {
DebugOnly<bool> success = mFront->CopyToTextureClient(mBack, &aPersistedRect, nullptr);
MOZ_ASSERT(success);
mFront->Unlock();
}
mDrawTarget = mBack->BorrowDrawTarget();
if (!mDrawTarget) {
return nullptr;
}
}
RefPtr<gfx::DrawTarget> dt(mDrawTarget);
return dt.forget();
}
bool
PersistentBufferProviderShared::ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT)
{
RefPtr<gfx::DrawTarget> dt(aDT);
MOZ_ASSERT(mDrawTarget == dt);
mDrawTarget = nullptr;
dt = nullptr;
mBack->Unlock();
mFront = mBack;
mBack = nullptr;
return true;
}
already_AddRefed<gfx::SourceSurface>
PersistentBufferProviderShared::BorrowSnapshot()
{
if (!mFront || mFront->IsLocked()) {
MOZ_ASSERT(false);
return nullptr;
}
if (!mFront->Lock(OpenMode::OPEN_READ)) {
return nullptr;
}
mDrawTarget = mFront->BorrowDrawTarget();
if (!mDrawTarget) {
mFront->Unlock();
}
mSnapshot = mDrawTarget->Snapshot();
RefPtr<SourceSurface> snapshot = mSnapshot;
return snapshot.forget();
}
void
PersistentBufferProviderShared::ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot)
{
RefPtr<SourceSurface> snapshot = aSnapshot;
MOZ_ASSERT(!snapshot || snapshot == mSnapshot);
mSnapshot = nullptr;
snapshot = nullptr;
mDrawTarget = nullptr;
mFront->Unlock();
}
} // namespace layers

Просмотреть файл

@ -13,6 +13,12 @@
#include "mozilla/gfx/Types.h"
namespace mozilla {
namespace gfx {
class SourceSurface;
class DrawTarget;
}
namespace layers {
class CopyableCanvasLayer;
@ -38,43 +44,112 @@ public:
*
* \param aPersistedRect This indicates the area of the DrawTarget that needs
* to have remained the same since the call to
* ReturnAndUseDT.
* ReturnDrawTarget.
*/
virtual already_AddRefed<gfx::DrawTarget> GetDT(const gfx::IntRect& aPersistedRect) = 0;
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) = 0;
/**
* Return a DrawTarget to the PersistentBufferProvider and indicate the
* contents of this DrawTarget is to be considered current by the
* BufferProvider. The caller should forget any references to the DrawTarget.
*/
virtual bool ReturnAndUseDT(already_AddRefed<gfx::DrawTarget> aDT) = 0;
virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0;
virtual already_AddRefed<gfx::SourceSurface> GetSnapshot() = 0;
protected:
virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() = 0;
virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;
virtual TextureClient* GetTextureClient() { return nullptr; }
};
class PersistentBufferProviderBasic : public PersistentBufferProvider
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic)
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic, override)
PersistentBufferProviderBasic(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aBackend);
explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget) : mDrawTarget(aTarget) {}
static already_AddRefed<PersistentBufferProviderBasic>
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::BackendType aBackend);
explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget);
virtual LayersBackend GetType() override { return LayersBackend::LAYERS_BASIC; }
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override;
virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;
virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
bool IsValid() { return !!mDrawTarget; }
virtual LayersBackend GetType() { return LayersBackend::LAYERS_BASIC; }
already_AddRefed<gfx::DrawTarget> GetDT(const gfx::IntRect& aPersistedRect) {
RefPtr<gfx::DrawTarget> dt(mDrawTarget);
return dt.forget();
}
bool ReturnAndUseDT(already_AddRefed<gfx::DrawTarget> aDT) {
RefPtr<gfx::DrawTarget> dt(aDT);
MOZ_ASSERT(mDrawTarget == dt);
return true;
}
virtual already_AddRefed<gfx::SourceSurface> GetSnapshot() { return mDrawTarget->Snapshot(); }
private:
~PersistentBufferProviderBasic();
RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<gfx::SourceSurface> mSnapshot;
};
/**
* Provides access to a buffer which can be sent to the compositor without
* requiring a copy.
*/
class PersistentBufferProviderShared : public PersistentBufferProvider
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared, override)
static already_AddRefed<PersistentBufferProviderShared>
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
CompositableForwarder* aFwd);
virtual LayersBackend GetType() override { return LayersBackend::LAYERS_CLIENT; }
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override;
virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;
virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
TextureClient* GetTextureClient() override {
return mFront;
}
protected:
PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
CompositableForwarder* aFwd,
RefPtr<TextureClient>& aTexture);
~PersistentBufferProviderShared();
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
RefPtr<CompositableForwarder> mFwd;
RefPtr<TextureClient> mFront;
RefPtr<TextureClient> mBack;
RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<gfx::SourceSurface > mSnapshot;
};
struct AutoReturnSnapshot
{
PersistentBufferProvider* mBufferProvider;
RefPtr<gfx::SourceSurface>* mSnapshot;
explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr)
: mBufferProvider(aProvider)
, mSnapshot(nullptr)
{}
~AutoReturnSnapshot()
{
if (mBufferProvider) {
mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget() : nullptr);
}
}
};
} // namespace layers

Просмотреть файл

@ -66,6 +66,30 @@ CanvasClientBridge::UpdateAsync(AsyncCanvasRenderer* aRenderer)
mAsyncID = asyncID;
}
void
CanvasClient2D::UpdateFromTexture(TextureClient* aTexture)
{
MOZ_ASSERT(aTexture);
if (!aTexture->IsSharedWithCompositor()) {
if (!AddTextureClient(aTexture)) {
return;
}
}
mBackBuffer = aTexture;
AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
t->mTextureClient = mBackBuffer;
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), aTexture->GetSize());
t->mFrameID = mFrameID;
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
GetForwarder()->UseTextures(this, textures);
aTexture->SyncWithObject(GetForwarder()->GetSyncObject());
}
void
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
#include "mozilla/layers/PersistentBufferProvider.h"
// Fix X11 header brain damage that conflicts with MaybeOneOf::None
#undef None
@ -76,6 +77,8 @@ public:
virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) {}
virtual void UpdateFromTexture(TextureClient* aTexture) {}
virtual void Updated() { }
protected:
@ -104,6 +107,8 @@ public:
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) override;
virtual void UpdateFromTexture(TextureClient* aBuffer) override;
virtual bool AddTextureClient(TextureClient* aTexture) override
{
MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);

Просмотреть файл

@ -130,7 +130,11 @@ ClientCanvasLayer::RenderLayer()
Painted();
FirePreTransactionCallback();
if (mBufferProvider && mBufferProvider->GetTextureClient()) {
mCanvasClient->UpdateFromTexture(mBufferProvider->GetTextureClient());
} else {
mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
}
FireDidTransactionCallback();

Просмотреть файл

@ -848,6 +848,15 @@ ClientLayerManager::DependsOnStaleDevice() const
return gfxPlatform::GetPlatform()->GetDeviceCounter() != mDeviceCounter;
}
already_AddRefed<PersistentBufferProvider>
ClientLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
gfx::SurfaceFormat aFormat)
{
return PersistentBufferProviderShared::Create(aSize, aFormat, AsShadowForwarder());
}
ClientLayer::~ClientLayer()
{
if (HasShadow()) {

Просмотреть файл

@ -246,6 +246,9 @@ public:
void AddDidCompositeObserver(DidCompositeObserver* aObserver);
void RemoveDidCompositeObserver(DidCompositeObserver* aObserver);
virtual already_AddRefed<PersistentBufferProvider>
CreatePersistentBufferProvider(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) override;
protected:
enum TransactionPhase {
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD