mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1167235 - Part 3: Switch CanvasRenderingContext2D to use the new BufferProvider API. r=nical
This commit is contained in:
parent
369f921871
commit
e2b3274f64
@ -87,6 +87,7 @@
|
||||
#include "mozilla/gfx/PatternHelpers.h"
|
||||
#include "mozilla/ipc/DocumentRendererParent.h"
|
||||
#include "mozilla/ipc/PDocumentRendererParent.h"
|
||||
#include "mozilla/layers/PersistentBufferProvider.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -820,6 +821,7 @@ public:
|
||||
// Since SkiaGL default to store drawing command until flush
|
||||
// We will have to flush it before present.
|
||||
context->mTarget->Flush();
|
||||
context->ReturnTarget();
|
||||
}
|
||||
|
||||
static void DidTransactionCallback(void* aData)
|
||||
@ -1034,7 +1036,9 @@ CanvasRenderingContext2D::Reset()
|
||||
gCanvasAzureMemoryUsed -= mWidth * mHeight * 4;
|
||||
}
|
||||
|
||||
ReturnTarget();
|
||||
mTarget = nullptr;
|
||||
mBufferProvider = nullptr;
|
||||
|
||||
// reset hit regions
|
||||
mHitRegionsOptions.ClearAndRetainStorage();
|
||||
@ -1186,9 +1190,18 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
|
||||
}
|
||||
#endif
|
||||
|
||||
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
|
||||
RefPtr<DrawTarget> oldTarget = mTarget;
|
||||
RefPtr<SourceSurface> snapshot;
|
||||
Matrix transform;
|
||||
|
||||
if (mTarget) {
|
||||
snapshot = mTarget->Snapshot();
|
||||
transform = mTarget->GetTransform();
|
||||
} else {
|
||||
MOZ_ASSERT(mBufferProvider);
|
||||
snapshot = mBufferProvider->GetSnapshot();
|
||||
}
|
||||
mTarget = nullptr;
|
||||
mBufferProvider = nullptr;
|
||||
mResetLayer = true;
|
||||
|
||||
// Recreate target using the new rendering mode
|
||||
@ -1208,7 +1221,7 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
|
||||
mTarget->PushClip(CurrentState().clipsPushed[i]);
|
||||
}
|
||||
|
||||
mTarget->SetTransform(oldTarget->GetTransform());
|
||||
mTarget->SetTransform(transform);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1332,6 +1345,15 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
|
||||
return mRenderingMode;
|
||||
}
|
||||
|
||||
if (mBufferProvider && mode == mRenderingMode) {
|
||||
mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
|
||||
if (mTarget) {
|
||||
return mRenderingMode;
|
||||
} else {
|
||||
mBufferProvider = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the dimensions are sane
|
||||
IntSize size(mWidth, mHeight);
|
||||
if (size.width <= gfxPrefs::MaxCanvasSize() &&
|
||||
@ -1350,11 +1372,12 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
|
||||
nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
|
||||
}
|
||||
|
||||
if (layerManager) {
|
||||
if (layerManager) {
|
||||
if (mode == RenderingMode::OpenGLBackendMode &&
|
||||
gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
|
||||
CheckSizeForSkiaGL(size)) {
|
||||
DemoteOldestContextIfNecessary();
|
||||
mBufferProvider = nullptr;
|
||||
|
||||
#if USE_SKIA_GPU
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
@ -1369,17 +1392,19 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!mTarget) {
|
||||
mTarget = layerManager->CreateDrawTarget(size, format);
|
||||
}
|
||||
} else {
|
||||
mTarget = layerManager->CreateDrawTarget(size, format);
|
||||
mode = RenderingMode::SoftwareBackendMode;
|
||||
}
|
||||
} else {
|
||||
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
|
||||
mode = RenderingMode::SoftwareBackendMode;
|
||||
}
|
||||
|
||||
if (!mBufferProvider) {
|
||||
mBufferProvider = layerManager->CreatePersistentBufferProvider(size, format);
|
||||
}
|
||||
}
|
||||
|
||||
if (mBufferProvider) {
|
||||
mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
|
||||
} else if (!mTarget) {
|
||||
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
|
||||
mode = RenderingMode::SoftwareBackendMode;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTarget) {
|
||||
@ -1496,6 +1521,17 @@ CanvasRenderingContext2D::ClearTarget()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::ReturnTarget()
|
||||
{
|
||||
if (mTarget && mBufferProvider) {
|
||||
CurrentState().transform = mTarget->GetTransform();
|
||||
DrawTarget* oldDT = mTarget;
|
||||
mTarget = nullptr;
|
||||
mBufferProvider->ReturnAndUseDT(oldDT);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasRenderingContext2D::InitializeWithSurface(nsIDocShell *shell,
|
||||
gfxASurface *surface,
|
||||
@ -2382,9 +2418,7 @@ void
|
||||
CanvasRenderingContext2D::ClearRect(double x, double y, double w,
|
||||
double h)
|
||||
{
|
||||
if (!mTarget) {
|
||||
return;
|
||||
}
|
||||
EnsureTarget();
|
||||
|
||||
mTarget->ClearRect(mgfx::Rect(x, y, w, h));
|
||||
|
||||
@ -2545,6 +2579,7 @@ CanvasRenderingContext2D::BeginPath()
|
||||
void
|
||||
CanvasRenderingContext2D::Fill(const CanvasWindingRule& winding)
|
||||
{
|
||||
EnsureTarget();
|
||||
EnsureUserSpacePath(winding);
|
||||
|
||||
if (!mPath) {
|
||||
@ -2590,6 +2625,7 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& path, const CanvasWindingR
|
||||
void
|
||||
CanvasRenderingContext2D::Stroke()
|
||||
{
|
||||
EnsureTarget();
|
||||
EnsureUserSpacePath();
|
||||
|
||||
if (!mPath) {
|
||||
@ -2725,6 +2761,8 @@ bool CanvasRenderingContext2D::DrawCustomFocusRing(mozilla::dom::Element& aEleme
|
||||
void
|
||||
CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
|
||||
{
|
||||
EnsureTarget();
|
||||
|
||||
EnsureUserSpacePath(winding);
|
||||
|
||||
if (!mPath) {
|
||||
@ -5156,6 +5194,7 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
|
||||
bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
|
||||
int32_t dirtyWidth, int32_t dirtyHeight)
|
||||
{
|
||||
EnsureTarget();
|
||||
if (mDrawObserver) {
|
||||
mDrawObserver->DidDrawCall(CanvasDrawObserver::DrawCallType::PutImageData);
|
||||
}
|
||||
@ -5347,8 +5386,11 @@ static uint8_t g2DContextLayerUserData;
|
||||
uint32_t
|
||||
CanvasRenderingContext2D::SkiaGLTex() const
|
||||
{
|
||||
MOZ_ASSERT(IsTargetValid());
|
||||
return (uint32_t)(uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE);
|
||||
if (!mTarget) {
|
||||
return 0;
|
||||
}
|
||||
MOZ_ASSERT(IsTargetValid());
|
||||
return (uint32_t)(uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE);
|
||||
}
|
||||
|
||||
void CanvasRenderingContext2D::RemoveDrawObserver()
|
||||
@ -5359,6 +5401,26 @@ void CanvasRenderingContext2D::RemoveDrawObserver()
|
||||
}
|
||||
}
|
||||
|
||||
PersistentBufferProvider*
|
||||
CanvasRenderingContext2D::GetBufferProvider(LayerManager* aManager)
|
||||
{
|
||||
if (mBufferProvider) {
|
||||
return mBufferProvider;
|
||||
}
|
||||
|
||||
if (!mTarget) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mBufferProvider = aManager->CreatePersistentBufferProvider(mTarget->GetSize(), mTarget->GetFormat());
|
||||
|
||||
RefPtr<SourceSurface> surf = mTarget->Snapshot();
|
||||
|
||||
mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), mTarget->GetSize()));
|
||||
mTarget->CopySurface(surf, IntRect(IntPoint(), mTarget->GetSize()), IntPoint());
|
||||
|
||||
return mBufferProvider;
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
@ -5375,15 +5437,13 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
// we have nothing to paint and there is no need to create a surface just
|
||||
// to paint nothing. Also, EnsureTarget() can cause creation of a persistent
|
||||
// layer manager which must NOT happen during a paint.
|
||||
if (!mTarget || !IsTargetValid()) {
|
||||
if ((!mBufferProvider && !mTarget) || !IsTargetValid()) {
|
||||
// No DidTransactionCallback will be received, so mark the context clean
|
||||
// now so future invalidations will be dispatched.
|
||||
MarkContextClean();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mTarget->Flush();
|
||||
|
||||
if (!mResetLayer && aOldLayer) {
|
||||
CanvasRenderingContext2DUserData* userData =
|
||||
static_cast<CanvasRenderingContext2DUserData*>(
|
||||
@ -5399,7 +5459,8 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mFrontbufferGLTex = skiaGLTex;
|
||||
} else {
|
||||
data.mDrawTarget = mTarget;
|
||||
PersistentBufferProvider *provider = GetBufferProvider(aManager);
|
||||
data.mBufferProvider = provider;
|
||||
}
|
||||
|
||||
if (userData && userData->IsForContext(this) && aOldLayer->IsDataValid(data)) {
|
||||
@ -5437,18 +5498,19 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
data.mSize = nsIntSize(mWidth, mHeight);
|
||||
data.mHasAlpha = !mOpaque;
|
||||
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
|
||||
|
||||
GLuint skiaGLTex = SkiaGLTex();
|
||||
if (skiaGLTex) {
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
|
||||
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
MOZ_ASSERT(glue);
|
||||
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mFrontbufferGLTex = skiaGLTex;
|
||||
} else {
|
||||
data.mDrawTarget = mTarget;
|
||||
PersistentBufferProvider *provider = GetBufferProvider(aManager);
|
||||
data.mBufferProvider = provider;
|
||||
}
|
||||
|
||||
canvasLayer->Initialize(data);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "FilterSupport.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "Layers.h"
|
||||
|
||||
class nsGlobalWindow;
|
||||
class nsXULElement;
|
||||
@ -456,6 +457,7 @@ public:
|
||||
NS_IMETHOD SetIsOpaque(bool isOpaque) override;
|
||||
bool GetIsOpaque() override { return mOpaque; }
|
||||
NS_IMETHOD Reset() override;
|
||||
mozilla::layers::PersistentBufferProvider* GetBufferProvider(mozilla::layers::LayerManager* aManager);
|
||||
already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager) override;
|
||||
@ -637,11 +639,17 @@ protected:
|
||||
*/
|
||||
void ClearTarget();
|
||||
|
||||
/*
|
||||
* Returns the target to the buffer provider. i.e. this will queue a frame for
|
||||
* rendering.
|
||||
*/
|
||||
void ReturnTarget();
|
||||
|
||||
/**
|
||||
* Check if the target is valid after calling EnsureTarget.
|
||||
*/
|
||||
bool IsTargetValid() const {
|
||||
return mTarget != sErrorTarget && mTarget != nullptr;
|
||||
return (sErrorTarget == nullptr || mTarget != sErrorTarget) && (mBufferProvider != nullptr || mTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -715,6 +723,8 @@ protected:
|
||||
// sErrorTarget.
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
|
||||
|
||||
mozilla::RefPtr<mozilla::layers::PersistentBufferProvider> mBufferProvider;
|
||||
|
||||
uint32_t SkiaGLTex() const;
|
||||
|
||||
// This observes our draw calls at the beginning of the canvas
|
||||
|
@ -48,10 +48,8 @@ public:
|
||||
*/
|
||||
virtual bool ReturnAndUseDT(gfx::DrawTarget* aDT) = 0;
|
||||
|
||||
protected:
|
||||
friend class CopyableCanvasLayer;
|
||||
|
||||
virtual TemporaryRef<gfx::SourceSurface> GetSnapshot() = 0;
|
||||
protected:
|
||||
};
|
||||
|
||||
class PersistentBufferProviderBasic : public PersistentBufferProvider
|
||||
|
Loading…
Reference in New Issue
Block a user