зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1724839 - Don't use BasicLayerManager for painting ImageBitmap <canvas> elements. r=jrmuizel
Differential Revision: https://phabricator.services.mozilla.com/D122171
This commit is contained in:
Родитель
a1d0abeb81
Коммит
8a447ade17
|
@ -81,6 +81,9 @@ class ImageBitmapRenderingContext final
|
|||
virtual already_AddRefed<Layer> GetCanvasLayer(
|
||||
nsDisplayListBuilder* aBuilder, Layer* aOldLayer,
|
||||
LayerManager* aManager) override;
|
||||
virtual already_AddRefed<layers::Image> GetAsImage() override {
|
||||
return ClipToIntrinsicSize();
|
||||
}
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) override;
|
||||
virtual void MarkContextClean() override;
|
||||
|
|
|
@ -39,6 +39,7 @@ class CanvasLayer;
|
|||
class CanvasRenderer;
|
||||
class CompositableHandle;
|
||||
class Layer;
|
||||
class Image;
|
||||
class LayerManager;
|
||||
class LayerTransactionChild;
|
||||
class PersistentBufferProvider;
|
||||
|
@ -146,6 +147,9 @@ class nsICanvasRenderingContextInternal : public nsISupports,
|
|||
virtual already_AddRefed<Layer> GetCanvasLayer(
|
||||
mozilla::nsDisplayListBuilder* builder, Layer* oldLayer,
|
||||
LayerManager* manager) = 0;
|
||||
virtual already_AddRefed<mozilla::layers::Image> GetAsImage() {
|
||||
return nullptr;
|
||||
}
|
||||
virtual bool UpdateWebRenderCanvasData(
|
||||
mozilla::nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData) {
|
||||
|
|
|
@ -1142,6 +1142,18 @@ already_AddRefed<Layer> HTMLCanvasElement::GetCanvasLayer(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<Image> HTMLCanvasElement::GetAsImage() {
|
||||
if (mCurrentContext) {
|
||||
return mCurrentContext->GetAsImage();
|
||||
}
|
||||
|
||||
if (mOffscreenCanvas) {
|
||||
MOZ_CRASH("todo");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool HTMLCanvasElement::UpdateWebRenderCanvasData(
|
||||
nsDisplayListBuilder* aBuilder, WebRenderCanvasData* aCanvasData) {
|
||||
if (mCurrentContext) {
|
||||
|
|
|
@ -301,6 +301,7 @@ class HTMLCanvasElement final : public nsGenericHTMLElement,
|
|||
already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
Layer* aOldLayer,
|
||||
LayerManager* aManager);
|
||||
already_AddRefed<layers::Image> GetAsImage();
|
||||
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
|
||||
WebRenderCanvasData* aCanvasData);
|
||||
bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
|
||||
|
|
|
@ -307,6 +307,51 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
|
|||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aCtx) override {
|
||||
nsHTMLCanvasFrame* f = static_cast<nsHTMLCanvasFrame*>(Frame());
|
||||
HTMLCanvasElement* canvas = HTMLCanvasElement::FromNode(f->GetContent());
|
||||
|
||||
nsRect area = f->GetContentRectRelativeToSelf() + ToReferenceFrame();
|
||||
nsIntSize canvasSizeInPx = f->GetCanvasSize();
|
||||
|
||||
nsPresContext* presContext = f->PresContext();
|
||||
canvas->HandlePrintCallback(presContext);
|
||||
|
||||
if (canvasSizeInPx.width <= 0 || canvasSizeInPx.height <= 0 ||
|
||||
area.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx);
|
||||
AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx);
|
||||
|
||||
nsRect dest = nsLayoutUtils::ComputeObjectDestRect(
|
||||
area, intrinsicSize, intrinsicRatio, f->StylePosition());
|
||||
|
||||
gfxRect destGFXRect = presContext->AppUnitsToGfxUnits(dest);
|
||||
|
||||
// Transform the canvas into the right place
|
||||
gfxPoint p = destGFXRect.TopLeft();
|
||||
Matrix transform = Matrix::Translation(p.x, p.y);
|
||||
transform.PreScale(destGFXRect.Width() / canvasSizeInPx.width,
|
||||
destGFXRect.Height() / canvasSizeInPx.height);
|
||||
|
||||
if (RefPtr<layers::Image> image = canvas->GetAsImage()) {
|
||||
RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
|
||||
if (!surface || !surface->IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfxContextMatrixAutoSaveRestore saveMatrix(aCtx);
|
||||
aCtx->Multiply(transform);
|
||||
|
||||
gfx::IntSize size = surface->GetSize();
|
||||
aCtx->GetDrawTarget()->FillRect(
|
||||
Rect(0, 0, size.width, size.height),
|
||||
SurfacePattern(surface, ExtendMode::CLAMP, Matrix(),
|
||||
nsLayoutUtils::GetSamplingFilterForFrame(f)));
|
||||
return;
|
||||
}
|
||||
|
||||
// This currently uses BasicLayerManager to re-use the code for extracting
|
||||
// the current CanvasRenderer/Image and generating DrawTarget rendering
|
||||
// commands for it.
|
||||
|
|
Загрузка…
Ссылка в новой задаче