зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1401609 - Add UpdateWebRenderCanvasData() to handle CanvasRenderer re-creation r=jrmuizel,mstange
This commit is contained in:
Родитель
831f2ed98f
Коммит
23069babc9
|
@ -127,6 +127,8 @@
|
|||
#include "mozilla/StyleSetHandle.h"
|
||||
#include "mozilla/StyleSetHandleInlines.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/WebRenderUserData.h"
|
||||
#include "mozilla/layers/WebRenderCanvasRenderer.h"
|
||||
#include "mozilla/ServoCSSParser.h"
|
||||
|
||||
#undef free // apparently defined by some windows header, clashing with a free()
|
||||
|
@ -6217,6 +6219,64 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
return canvasLayer.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
CanvasRenderingContext2D::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
if (mOpaque || mIsSkiaGL) {
|
||||
// If we're opaque then make sure we have a surface so we paint black
|
||||
// instead of transparent.
|
||||
// If we're using SkiaGL, then SkiaGLTex() below needs the target to
|
||||
// be accessible.
|
||||
EnsureTarget();
|
||||
}
|
||||
|
||||
// Don't call EnsureTarget() ... if there isn't already a surface, then
|
||||
// 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 (!mBufferProvider && !IsTargetValid()) {
|
||||
// No DidTransactionCallback will be received, so mark the context clean
|
||||
// now so future invalidations will be dispatched.
|
||||
MarkContextClean();
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if(!mResetLayer && renderer) {
|
||||
CanvasInitializeData data;
|
||||
|
||||
if (mIsSkiaGL) {
|
||||
GLuint skiaGLTex = SkiaGLTex();
|
||||
if (skiaGLTex) {
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
MOZ_ASSERT(glue);
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mFrontbufferGLTex = skiaGLTex;
|
||||
}
|
||||
}
|
||||
data.mBufferProvider = mBufferProvider;
|
||||
|
||||
if (renderer->IsDataValid(data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(renderer);
|
||||
mResetLayer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CanvasRenderingContext2D::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
|
|
|
@ -467,6 +467,10 @@ public:
|
|||
already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
Layer* aOldLayer,
|
||||
LayerManager* aManager) override;
|
||||
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) override;
|
||||
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer) override;
|
||||
virtual bool ShouldForceInactiveLayer(LayerManager* aManager) override;
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "ScopedGLHelpers.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
#include "mozilla/layers/WebRenderUserData.h"
|
||||
#include "mozilla/layers/WebRenderCanvasRenderer.h"
|
||||
|
||||
// Local
|
||||
#include "CanvasUtils.h"
|
||||
|
@ -1350,6 +1352,28 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
|
|||
return canvasLayer.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if(!mResetLayer && renderer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(renderer);
|
||||
mResetLayer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
|
|
|
@ -434,6 +434,11 @@ public:
|
|||
already_AddRefed<Layer>
|
||||
GetCanvasLayer(nsDisplayListBuilder* builder, Layer* oldLayer,
|
||||
LayerManager* manager) override;
|
||||
|
||||
bool
|
||||
UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) override;
|
||||
|
||||
bool
|
||||
InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer) override;
|
||||
|
|
|
@ -29,6 +29,7 @@ class CanvasLayer;
|
|||
class CanvasRenderer;
|
||||
class Layer;
|
||||
class LayerManager;
|
||||
class WebRenderCanvasData;
|
||||
} // namespace layers
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
typedef mozilla::layers::CanvasRenderer CanvasRenderer;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::layers::WebRenderCanvasData WebRenderCanvasData;
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
|
||||
|
||||
|
@ -140,6 +142,8 @@ public:
|
|||
virtual already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* builder,
|
||||
Layer *oldLayer,
|
||||
LayerManager *manager) = 0;
|
||||
virtual bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) { return false; }
|
||||
virtual bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer) { return true; }
|
||||
|
||||
|
|
|
@ -1219,6 +1219,37 @@ HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLCanvasElement::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
if (mCurrentContext) {
|
||||
return mCurrentContext->UpdateWebRenderCanvasData(aBuilder, aCanvasData);
|
||||
}
|
||||
if (mOffscreenCanvas) {
|
||||
CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer();
|
||||
|
||||
if(!mResetLayer && renderer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
renderer = aCanvasData->CreateCanvasRenderer();
|
||||
if (!InitializeCanvasRenderer(aBuilder, renderer)) {
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(renderer);
|
||||
mResetLayer = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clear CanvasRenderer of WebRenderCanvasData
|
||||
aCanvasData->ClearCanvasRenderer();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLCanvasElement::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
|
@ -1235,7 +1266,7 @@ HTMLCanvasElement::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
|||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -35,6 +35,7 @@ class Image;
|
|||
class Layer;
|
||||
class LayerManager;
|
||||
class SharedSurfaceTextureClient;
|
||||
class WebRenderCanvasData;
|
||||
} // namespace layers
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
|
@ -127,6 +128,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
|
|||
typedef layers::CanvasLayer CanvasLayer;
|
||||
typedef layers::Layer Layer;
|
||||
typedef layers::LayerManager LayerManager;
|
||||
typedef layers::WebRenderCanvasData WebRenderCanvasData;
|
||||
|
||||
public:
|
||||
explicit HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
|
||||
|
@ -306,6 +308,8 @@ public:
|
|||
already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
Layer *aOldLayer,
|
||||
LayerManager *aManager);
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData);
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer);
|
||||
// Should return true if the canvas layer should always be marked inactive.
|
||||
|
|
|
@ -40,7 +40,9 @@ WebRenderCommandBuilder::EmptyTransaction()
|
|||
for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) {
|
||||
RefPtr<WebRenderCanvasData> canvasData = iter.Get()->GetKey();
|
||||
WebRenderCanvasRendererAsync* canvas = canvasData->GetCanvasRenderer();
|
||||
canvas->UpdateCompositableClient();
|
||||
if (canvas) {
|
||||
canvas->UpdateCompositableClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -255,13 +255,22 @@ WebRenderCanvasData::ClearCachedResources()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCanvasData::ClearCanvasRenderer()
|
||||
{
|
||||
mCanvasRenderer = nullptr;
|
||||
}
|
||||
|
||||
WebRenderCanvasRendererAsync*
|
||||
WebRenderCanvasData::GetCanvasRenderer()
|
||||
{
|
||||
if (!mCanvasRenderer) {
|
||||
mCanvasRenderer = MakeUnique<WebRenderCanvasRendererAsync>(mWRManager);
|
||||
}
|
||||
return mCanvasRenderer.get();
|
||||
}
|
||||
|
||||
WebRenderCanvasRendererAsync*
|
||||
WebRenderCanvasData::CreateCanvasRenderer()
|
||||
{
|
||||
mCanvasRenderer = MakeUnique<WebRenderCanvasRendererAsync>(mWRManager);
|
||||
return mCanvasRenderer.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,9 @@ public:
|
|||
virtual UserDataType GetType() override { return UserDataType::eCanvas; }
|
||||
static UserDataType Type() { return UserDataType::eCanvas; }
|
||||
|
||||
void ClearCanvasRenderer();
|
||||
WebRenderCanvasRendererAsync* GetCanvasRenderer();
|
||||
WebRenderCanvasRendererAsync* CreateCanvasRenderer();
|
||||
void ClearCachedResources() override;
|
||||
protected:
|
||||
UniquePtr<WebRenderCanvasRendererAsync> mCanvasRenderer;
|
||||
|
|
|
@ -141,16 +141,13 @@ public:
|
|||
bool isRecycled;
|
||||
RefPtr<WebRenderCanvasData> canvasData =
|
||||
aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderCanvasData>(this, &isRecycled);
|
||||
nsHTMLCanvasFrame* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
if (!canvasFrame->UpdateWebRenderCanvasData(aDisplayListBuilder, canvasData)) {
|
||||
return true;
|
||||
}
|
||||
WebRenderCanvasRendererAsync* data =
|
||||
static_cast<WebRenderCanvasRendererAsync*>(canvasData->GetCanvasRenderer());
|
||||
|
||||
if (!isRecycled) {
|
||||
nsHTMLCanvasFrame* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame);
|
||||
if (!canvasFrame->InitializeCanvasRenderer(aDisplayListBuilder, data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(data);
|
||||
data->UpdateCompositableClient();
|
||||
|
||||
// Push IFrame for async image pipeline.
|
||||
|
@ -461,11 +458,11 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
bool
|
||||
nsHTMLCanvasFrame::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer)
|
||||
nsHTMLCanvasFrame::UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData)
|
||||
{
|
||||
HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(GetContent());
|
||||
return element->InitializeCanvasRenderer(aBuilder, aRenderer);
|
||||
return element->UpdateWebRenderCanvasData(aBuilder, aCanvasData);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace mozilla {
|
|||
namespace layers {
|
||||
class Layer;
|
||||
class LayerManager;
|
||||
class WebRenderCanvasData;
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -32,6 +33,7 @@ public:
|
|||
typedef mozilla::layers::CanvasRenderer CanvasRenderer;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::layers::WebRenderCanvasData WebRenderCanvasData;
|
||||
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
|
||||
|
||||
NS_DECL_QUERYFRAME
|
||||
|
@ -53,8 +55,9 @@ public:
|
|||
LayerManager* aManager,
|
||||
nsDisplayItem* aItem,
|
||||
const ContainerLayerParameters& aContainerParameters);
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasRenderer* aRenderer);
|
||||
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData);
|
||||
|
||||
/* get the size of the canvas's image */
|
||||
nsIntSize GetCanvasSize();
|
||||
|
|
|
@ -6,7 +6,7 @@ fuzzy-if(Android,8,1000) == size-1.html size-1-ref.html
|
|||
== image-rendering-test.html image-rendering-ref.html
|
||||
== image-shadow.html image-shadow-ref.html
|
||||
|
||||
asserts-if(cocoaWidget,0-2) fails-if(webrender) == size-change-1.html size-change-1-ref.html
|
||||
asserts-if(cocoaWidget,0-2) == size-change-1.html size-change-1-ref.html
|
||||
|
||||
random-if(cocoaWidget) == subpixel-1.html about:blank # see bug 1192616, re-enable once we're off the pandaboards
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче