Tear down ImageBuffer's reference to HTMLCanvasElement via ImageBufferClient
As a first step to remove ImageBuffer(Surface), this CL refactors the
followings:
- Remove ImageBufferClient and break ImageBuffer's reference to canvas element
- Move ImageBuffer's various functions to HTMLCanvasElement, including
UpdateGPUMemoryUsage, DisableAcceleration, gpu_readback_frame computation,
etc.)
- Introduce abstract class CanvasResourceHost as a way for
Canvas2DLayerBridge (and temporarily, RecordingImageBufferSurface) to point
to HTMLCanvasElement.
- Reconcile UpdateGPUMemoryUsage() and UpdateExternallyAllocatedMemory() in one
single function.
Bug: 776806
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I7b3fdfad476c02b6e4368d3ef1e5eca9688cbf5b
Reviewed-on: https://chromium-review.googlesource.com/774996
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Justin Novosad <junov@chromium.org>
Commit-Queue: Olivia Lai <xlai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#518980}
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 8ff3278..59635f3 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -81,7 +81,6 @@
#include "platform/graphics/paint/PaintCanvas.h"
#include "platform/image-encoders/ImageEncoderUtils.h"
#include "platform/runtime_enabled_features.h"
-#include "platform/transforms/AffineTransform.h"
#include "platform/wtf/CheckedNumeric.h"
#include "platform/wtf/PtrUtil.h"
#include "public/platform/Platform.h"
@@ -112,8 +111,8 @@
// to be equivalent to memory used by 100 accelerated canvases, each has a size
// of 1000*500 and 2d context.
// Each such canvas occupies 4000000 = 1000 * 500 * 2 * 4 bytes, where 2 is the
-// gpuBufferCount in ImageBuffer::updateGPUMemoryUsage() and 4 means four bytes
-// per pixel per buffer.
+// gpuBufferCount in UpdateMemoryUsage() and 4 means four bytes per pixel per
+// buffer.
const int kMaxGlobalGPUMemoryUsage =
4000000 * kMaxGlobalAcceleratedImageBufferCount;
@@ -140,17 +139,23 @@
PageVisibilityObserver(document.GetPage()),
size_(kDefaultWidth, kDefaultHeight),
ignore_reset_(false),
- externally_allocated_memory_(0),
origin_clean_(true),
did_fail_to_create_image_buffer_(false),
image_buffer_is_clear_(false),
- surface_layer_bridge_(nullptr) {
+ surface_layer_bridge_(nullptr),
+ gpu_memory_usage_(0),
+ externally_allocated_memory_(0),
+ gpu_readback_invoked_in_current_frame_(false),
+ gpu_readback_successive_frames_(0) {
CanvasMetrics::CountCanvasContextUsage(CanvasMetrics::kCanvasCreated);
UseCounter::Count(document, WebFeature::kHTMLCanvasElement);
}
DEFINE_NODE_FACTORY(HTMLCanvasElement)
+intptr_t HTMLCanvasElement::global_gpu_memory_usage_ = 0;
+unsigned HTMLCanvasElement::global_accelerated_context_count_ = 0;
+
HTMLCanvasElement::~HTMLCanvasElement() {
if (surface_layer_bridge_ && surface_layer_bridge_->GetWebLayer()) {
GraphicsLayer::UnregisterContentsLayer(
@@ -170,9 +175,15 @@
}
if (image_buffer_) {
- image_buffer_->SetClient(nullptr);
+ image_buffer_->OnCanvasDisposed();
image_buffer_ = nullptr;
}
+
+ if (gpu_memory_usage_) {
+ DCHECK_GT(global_accelerated_context_count_, 0u);
+ global_accelerated_context_count_--;
+ }
+ global_gpu_memory_usage_ -= gpu_memory_usage_;
}
void HTMLCanvasElement::ParseAttribute(
@@ -296,7 +307,7 @@
probe::didCreateCanvasContext(&GetDocument());
if (Is3d()) {
- UpdateExternallyAllocatedMemory();
+ UpdateMemoryUsage();
}
LayoutObject* layout_object = this->GetLayoutObject();
@@ -380,8 +391,26 @@
}
void HTMLCanvasElement::FinalizeFrame() {
- if (GetImageBuffer())
+ if (GetImageBuffer()) {
+ // Compute to determine whether disable accleration is needed
+ if (IsAccelerated() &&
+ CanvasHeuristicParameters::kGPUReadbackForcesNoAcceleration &&
+ !RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled()) {
+ if (gpu_readback_invoked_in_current_frame_) {
+ gpu_readback_successive_frames_++;
+ gpu_readback_invoked_in_current_frame_ = false;
+ } else {
+ gpu_readback_successive_frames_ = 0;
+ }
+
+ if (gpu_readback_successive_frames_ >=
+ CanvasHeuristicParameters::kGPUReadbackMinSuccessiveFrames) {
+ DisableAcceleration();
+ }
+ }
+
image_buffer_->FinalizeFrame();
+ }
// If the canvas is visible, notifying listeners is taken
// care of in the in doDeferredPaintInvalidation, which allows
@@ -395,7 +424,17 @@
did_notify_listeners_for_current_frame_ = false;
}
-void HTMLCanvasElement::DidDisableAcceleration() {
+void HTMLCanvasElement::DisableAcceleration() {
+ // Create and configure a recording (unaccelerated) surface.
+ std::unique_ptr<ImageBufferSurface> surface =
+ WTF::WrapUnique(new RecordingImageBufferSurface(
+ Size(), RecordingImageBufferSurface::kAllowFallback, ColorParams()));
+ if (image_buffer_) {
+ RestoreCanvasMatrixClipStack(surface->Canvas());
+ image_buffer_->SetSurface(std::move(surface));
+ UpdateMemoryUsage();
+ }
+
// We must force a paint invalidation on the canvas even if it's
// content did not change because it layer was destroyed.
DidDraw();
@@ -918,13 +957,13 @@
// accelerated canvases), the compositor starves and browser becomes laggy.
// Thus, we should stop allocating more GPU memory to new canvases created
// when the current memory usage exceeds the threshold.
- if (ImageBuffer::GetGlobalGPUMemoryUsage() >= kMaxGlobalGPUMemoryUsage)
+ if (global_gpu_memory_usage_ >= kMaxGlobalGPUMemoryUsage)
return false;
// Allocating too many GPU resources can makes us run into the driver's
// resource limits. So we need to keep the number of texture resources
// under tight control
- if (ImageBuffer::GetGlobalAcceleratedImageBufferCount() >=
+ if (global_accelerated_context_count_ >=
kMaxGlobalAcceleratedImageBufferCount)
return false;
}
@@ -1080,13 +1119,12 @@
if (!surface)
return;
DCHECK(surface->IsValid());
+ surface->SetCanvasResourceHost(this);
image_buffer_ = ImageBuffer::Create(std::move(surface));
- DCHECK(image_buffer_);
- image_buffer_->SetClient(this);
did_fail_to_create_image_buffer_ = false;
- UpdateExternallyAllocatedMemory();
+ UpdateMemoryUsage();
if (Is3d()) {
// Early out for WebGL canvases
@@ -1124,42 +1162,6 @@
HTMLElement::TraceWrappers(visitor);
}
-void HTMLCanvasElement::UpdateExternallyAllocatedMemory() const {
- int buffer_count = 0;
- if (image_buffer_) {
- buffer_count++;
- if (image_buffer_->IsAccelerated()) {
- // The number of internal GPU buffers vary between one (stable
- // non-displayed state) and three (triple-buffered animations).
- // Adding 2 is a pessimistic but relevant estimate.
- // Note: These buffers might be allocated in GPU memory.
- buffer_count += 2;
- }
- }
- if (copied_image_)
- buffer_count++;
-
- // Multiplying number of buffers by bytes per pixel
- CheckedNumeric<intptr_t> checked_externally_allocated_memory =
- buffer_count * ColorParams().BytesPerPixel();
- if (Is3d()) {
- checked_externally_allocated_memory +=
- context_->ExternallyAllocatedBytesPerPixel();
- }
-
- checked_externally_allocated_memory *= width();
- checked_externally_allocated_memory *= height();
- intptr_t externally_allocated_memory =
- checked_externally_allocated_memory.ValueOrDefault(
- std::numeric_limits<intptr_t>::max());
-
- // Subtracting two intptr_t that are known to be positive will never
- // underflow.
- v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
- externally_allocated_memory - externally_allocated_memory_);
- externally_allocated_memory_ = externally_allocated_memory;
-}
-
PaintCanvas* HTMLCanvasElement::DrawingCanvas() {
return GetOrCreateImageBuffer() ? GetImageBuffer()->Canvas() : nullptr;
}
@@ -1193,17 +1195,6 @@
CreateImageBufferInternal(std::move(surface));
}
-void HTMLCanvasElement::EnsureUnacceleratedImageBuffer() {
- DCHECK(context_);
- if ((GetImageBuffer() && !GetImageBuffer()->IsAccelerated()) ||
- did_fail_to_create_image_buffer_)
- return;
- DiscardImageBuffer();
- image_buffer_ = ImageBuffer::Create(Size(), kInitializeImagePixels,
- context_->ColorParams());
- did_fail_to_create_image_buffer_ = !image_buffer_;
-}
-
scoped_refptr<Image> HTMLCanvasElement::CopiedImage(
SourceDrawingBuffer source_buffer,
AccelerationHint hint,
@@ -1235,7 +1226,7 @@
need_to_update |= context_->PaintRenderingResultsToCanvas(source_buffer);
if (need_to_update && GetOrCreateImageBuffer()) {
copied_image_ = GetImageBuffer()->NewImageSnapshot(hint, snapshot_reason);
- UpdateExternallyAllocatedMemory();
+ UpdateMemoryUsage();
}
return copied_image_;
}
@@ -1243,21 +1234,16 @@
void HTMLCanvasElement::DiscardImageBuffer() {
image_buffer_.reset();
dirty_rect_ = FloatRect();
- UpdateExternallyAllocatedMemory();
+ UpdateMemoryUsage();
}
void HTMLCanvasElement::ClearCopiedImage() {
if (copied_image_) {
copied_image_ = nullptr;
- UpdateExternallyAllocatedMemory();
+ UpdateMemoryUsage();
}
}
-AffineTransform HTMLCanvasElement::BaseTransform() const {
- DCHECK(GetImageBuffer() && !did_fail_to_create_image_buffer_);
- return image_buffer_->BaseTransform();
-}
-
void HTMLCanvasElement::PageVisibilityChanged() {
bool hidden = !GetPage()->IsPageVisible();
SetSuspendOffscreenCanvasAnimation(hidden);
@@ -1301,7 +1287,9 @@
std::unique_ptr<ImageBufferSurface> surface =
CreateAcceleratedImageBufferSurface(&msaa_sample_count);
if (surface) {
+ RestoreCanvasMatrixClipStack(surface->Canvas());
GetOrCreateImageBuffer()->SetSurface(std::move(surface));
+ UpdateMemoryUsage();
SetNeedsCompositingUpdate();
}
}
@@ -1361,7 +1349,7 @@
!RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled() &&
hint == kPreferNoAcceleration && GetImageBuffer() &&
GetImageBuffer()->IsAccelerated()) {
- GetImageBuffer()->DisableAcceleration();
+ DisableAcceleration();
}
image = RenderingContext()->GetImage(hint, reason);
if (!image) {
@@ -1538,4 +1526,58 @@
return GetDocument().GetStyleEngine().GetFontSelector();
}
+void HTMLCanvasElement::UpdateMemoryUsage() {
+ int non_gpu_buffer_count = 0;
+ int gpu_buffer_count = 0;
+ if (image_buffer_) {
+ non_gpu_buffer_count++;
+ if (image_buffer_->IsAccelerated()) {
+ // The number of internal GPU buffers vary between one (stable
+ // non-displayed state) and three (triple-buffered animations).
+ // Adding 2 is a pessimistic but relevant estimate.
+ // Note: These buffers might be allocated in GPU memory.
+ gpu_buffer_count = 2;
+ }
+ }
+
+ if (copied_image_)
+ non_gpu_buffer_count++;
+
+ if (Is3d())
+ non_gpu_buffer_count += context_->ExternallyAllocatedBufferCountPerPixel();
+
+ int multiplier = ColorParams().BytesPerPixel() * width() * height();
+ CheckedNumeric<intptr_t> checked_usage = 0;
+
+ // Re-computation of gpu memory usage is only carried out when there is a
+ // a change from acceleration to non-accleration or vice versa.
+ if (gpu_buffer_count && !gpu_memory_usage_) {
+ // Switch from non-acceleration mode to acceleration mode
+ checked_usage += multiplier * gpu_buffer_count;
+ intptr_t gpu_memory_usage =
+ checked_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max());
+
+ global_gpu_memory_usage_ += (gpu_memory_usage - gpu_memory_usage_);
+ gpu_memory_usage_ = gpu_memory_usage;
+ global_accelerated_context_count_++;
+ } else if (!gpu_buffer_count && gpu_memory_usage_) {
+ // Switch from acceleration mode to non-acceleration mode
+ DCHECK_GT(global_accelerated_context_count_, 0u);
+ global_accelerated_context_count_--;
+ global_gpu_memory_usage_ -= gpu_memory_usage_;
+ gpu_memory_usage_ = 0;
+ }
+
+ // Recomputation of externally memory usage computation is carried out
+ // in all cases.
+ checked_usage += multiplier * non_gpu_buffer_count;
+ intptr_t externally_allocated_memory =
+ checked_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max());
+ // Subtracting two intptr_t that are known to be positive will never
+ // underflow.
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+ externally_allocated_memory - externally_allocated_memory_);
+ externally_allocated_memory_ = externally_allocated_memory;
+}
+
} // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
index 6167745..4a5d7c1 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -44,9 +44,9 @@
#include "platform/bindings/ScriptWrappableVisitor.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntSize.h"
+#include "platform/graphics/CanvasResourceHost.h"
#include "platform/graphics/GraphicsTypes.h"
#include "platform/graphics/GraphicsTypes3D.h"
-#include "platform/graphics/ImageBufferClient.h"
#include "platform/graphics/OffscreenCanvasPlaceholder.h"
#include "platform/graphics/SurfaceLayerBridge.h"
#include "platform/heap/Handle.h"
@@ -55,7 +55,6 @@
namespace blink {
-class AffineTransform;
class CanvasColorParams;
class CanvasContextCreationAttributes;
class CanvasRenderingContext;
@@ -82,9 +81,9 @@
public CanvasImageSource,
public CanvasRenderingContextHost,
public WebSurfaceLayerBridgeObserver,
- public ImageBufferClient,
public ImageBitmapSource,
- public OffscreenCanvasPlaceholder {
+ public OffscreenCanvasPlaceholder,
+ public CanvasResourceHost {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HTMLCanvasElement);
USING_PRE_FINALIZER(HTMLCanvasElement, Dispose);
@@ -147,7 +146,6 @@
CanvasRenderingContext* RenderingContext() const { return context_.Get(); }
- void EnsureUnacceleratedImageBuffer();
scoped_refptr<Image> CopiedImage(SourceDrawingBuffer,
AccelerationHint,
SnapshotReason);
@@ -156,8 +154,6 @@
bool OriginClean() const;
void SetOriginTainted() { origin_clean_ = false; }
- AffineTransform BaseTransform() const;
-
bool Is3d() const;
bool Is2d() const;
bool IsAnimated2d() const;
@@ -204,11 +200,13 @@
void RegisterContentsLayer(WebLayer*) override;
void UnregisterContentsLayer(WebLayer*) override;
- // ImageBufferClient implementation
+ // CanvasResourceHost implementation
void NotifySurfaceInvalid() override;
- void DidDisableAcceleration() override;
void RestoreCanvasMatrixClipStack(PaintCanvas*) const override;
void SetNeedsCompositingUpdate() override;
+ void UpdateMemoryUsage() override;
+
+ void DisableAcceleration();
// ImageBitmapSource implementation
IntSize BitmapSourceSize() const override;
@@ -231,7 +229,6 @@
static void RegisterRenderingContextFactory(
std::unique_ptr<CanvasRenderingContextFactory>);
- void UpdateExternallyAllocatedMemory() const;
void StyleDidChange(const ComputedStyle* old_style,
const ComputedStyle& new_style);
@@ -269,6 +266,16 @@
bool IsWebGL2Enabled() const override;
bool IsWebGLBlocked() const override;
+ // Memory Management
+ static intptr_t GetGlobalGPUMemoryUsage() { return global_gpu_memory_usage_; }
+ static unsigned GetGlobalAcceleratedContextCount() {
+ return global_accelerated_context_count_;
+ }
+ intptr_t GetGPUMemoryUsage() { return gpu_memory_usage_; }
+ void DidInvokeGPUReadbackInCurrentFrame() {
+ gpu_readback_invoked_in_current_frame_ = true;
+ }
+
protected:
void DidMoveToNewDocument(Document& old_document) override;
@@ -322,8 +329,6 @@
bool ignore_reset_;
FloatRect dirty_rect_;
- mutable intptr_t externally_allocated_memory_;
-
bool origin_clean_;
// It prevents HTMLCanvasElement::buffer() from continuously re-attempting to
@@ -340,6 +345,15 @@
std::unique_ptr<::blink::SurfaceLayerBridge> surface_layer_bridge_;
bool did_notify_listeners_for_current_frame_ = false;
+
+ // GPU Memory Management
+ static intptr_t global_gpu_memory_usage_;
+ static unsigned global_accelerated_context_count_;
+ mutable intptr_t gpu_memory_usage_;
+ mutable intptr_t externally_allocated_memory_;
+
+ mutable bool gpu_readback_invoked_in_current_frame_;
+ int gpu_readback_successive_frames_;
};
} // namespace blink
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
index e7282f81..3e1fbc0 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -168,7 +168,7 @@
NOTREACHED();
return nullptr;
}
- virtual int ExternallyAllocatedBytesPerPixel() {
+ virtual int ExternallyAllocatedBufferCountPerPixel() {
NOTREACHED();
return 0;
}
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.cpp
index dcd8a3f..ca837ec 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.cpp
@@ -544,7 +544,7 @@
// resetTransform() resolves the non-invertible CTM state.
ModifiableState().ResetTransform();
- c->setMatrix(AffineTransformToSkMatrix(BaseTransform()));
+ c->setMatrix(AffineTransformToSkMatrix(AffineTransform()));
if (invertible_ctm)
path_.Transform(ctm);
@@ -1297,7 +1297,7 @@
float src_area = src_rect.Width() * src_rect.Height();
if (src_area >
CanvasHeuristicParameters::kDrawImageTextureUploadHardSizeLimit) {
- buffer->DisableAcceleration();
+ this->DisableAcceleration();
} else if (src_area > CanvasHeuristicParameters::
kDrawImageTextureUploadSoftSizeLimit) {
SkRect bounds = dst_rect;
@@ -1307,7 +1307,7 @@
if (src_area >
dst_area * CanvasHeuristicParameters::
kDrawImageTextureUploadSoftSizeLimitScaleThreshold) {
- buffer->DisableAcceleration();
+ this->DisableAcceleration();
}
}
}
@@ -1647,11 +1647,17 @@
}
WTF::ArrayBufferContents contents;
- if (!buffer->GetImageData(image_data_rect, contents)) {
+ bool is_gpu_readback_invoked = false;
+ if (!buffer->GetImageData(image_data_rect, contents,
+ &is_gpu_readback_invoked)) {
exception_state.ThrowRangeError("Out of memory at ImageData creation");
return nullptr;
}
+ if (is_gpu_readback_invoked) {
+ DidInvokeGPUReadbackInCurrentFrame();
+ }
+
NeedsFinalizeFrame();
// Convert pixels to proper storage format if needed
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h
index 26554d29..967335d0 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/BaseRenderingContext2D.h
@@ -234,8 +234,6 @@
virtual PaintCanvas* ExistingDrawingCanvas() const = 0;
virtual void DisableDeferral(DisableDeferralReason) = 0;
- virtual AffineTransform BaseTransform() const = 0;
-
virtual void DidDraw(const SkIRect& dirty_rect) = 0;
virtual bool StateHasFilter() = 0;
@@ -367,6 +365,9 @@
// Canvas is device independent
static const double kCDeviceScaleFactor;
+ virtual void DisableAcceleration() {}
+ virtual void DidInvokeGPUReadbackInCurrentFrame() {}
+
private:
void RealizeSaves();
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
index 430d007..41957f1 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
@@ -410,10 +410,6 @@
canvas()->DisableDeferral(reason);
}
-AffineTransform CanvasRenderingContext2D::BaseTransform() const {
- return canvas()->BaseTransform();
-}
-
String CanvasRenderingContext2D::font() const {
if (!GetState().HasRealizedFont())
return kDefaultFont;
@@ -1070,4 +1066,12 @@
return 0;
}
+void CanvasRenderingContext2D::DisableAcceleration() {
+ canvas()->DisableAcceleration();
+}
+
+void CanvasRenderingContext2D::DidInvokeGPUReadbackInCurrentFrame() {
+ canvas()->DidInvokeGPUReadbackInCurrentFrame();
+}
+
} // namespace blink
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h
index e27059df..a72cd92 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h
@@ -165,6 +165,8 @@
return CanvasRenderingContext::WouldTaintOrigin(
source, execution_context->GetSecurityOrigin());
}
+ void DisableAcceleration() override;
+ void DidInvokeGPUReadbackInCurrentFrame() override;
int Width() const final;
int Height() const final;
@@ -178,7 +180,6 @@
PaintCanvas* ExistingDrawingCanvas() const final;
void DisableDeferral(DisableDeferralReason) final;
- AffineTransform BaseTransform() const final;
void DidDraw(const SkIRect& dirty_rect) final; // overrides
// BaseRenderingContext2D and
// CanvasRenderingContext
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp
index 3e7f34cb..85f7afb 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -112,13 +112,13 @@
CanvasElement().RenderingContext());
}
intptr_t GetGlobalGPUMemoryUsage() const {
- return ImageBuffer::GetGlobalGPUMemoryUsage();
+ return HTMLCanvasElement::GetGlobalGPUMemoryUsage();
}
- unsigned GetGlobalAcceleratedImageBufferCount() const {
- return ImageBuffer::GetGlobalAcceleratedImageBufferCount();
+ unsigned GetGlobalAcceleratedContextCount() const {
+ return HTMLCanvasElement::GetGlobalAcceleratedContextCount();
}
intptr_t GetCurrentGPUMemoryUsage() const {
- return CanvasElement().GetImageBuffer()->GetGPUMemoryUsage();
+ return CanvasElement().GetGPUMemoryUsage();
}
void CreateContext(OpacityMode,
@@ -213,7 +213,7 @@
IntSize(800, 600), &page_clients, nullptr, override_settings_function_);
document_ = &dummy_page_holder_->GetDocument();
document_->documentElement()->SetInnerHTMLFromString(
- "<body><canvas id='c'></canvas></body>");
+ "<body><canvas id='c'></canvas><canvas id='d'></canvas></body>");
document_->View()->UpdateAllLifecyclePhases();
canvas_element_ = ToHTMLCanvasElement(document_->getElementById("c"));
@@ -253,8 +253,10 @@
std::unique_ptr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge(
const IntSize& size,
Canvas2DLayerBridge::AccelerationMode acceleration_mode) {
- return WTF::WrapUnique(
+ std::unique_ptr<Canvas2DLayerBridge> bridge = WTF::WrapUnique(
new Canvas2DLayerBridge(size, 0, acceleration_mode, CanvasColorParams()));
+ bridge->SetCanvasResourceHost(canvas_element_);
+ return bridge;
}
//============================================================================
@@ -870,42 +872,46 @@
// pixel per buffer, and 2 is an estimate of num of gpu buffers required
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
EXPECT_EQ(800, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
// Switching accelerated mode to non-accelerated mode
fake_accelerate_surface_ptr->SetIsAccelerated(false);
- CanvasElement().GetImageBuffer()->UpdateGPUMemoryUsage();
+ CanvasElement().UpdateMemoryUsage();
EXPECT_EQ(0, GetCurrentGPUMemoryUsage());
EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
// Switching non-accelerated mode to accelerated mode
fake_accelerate_surface_ptr->SetIsAccelerated(true);
- CanvasElement().GetImageBuffer()->UpdateGPUMemoryUsage();
+ CanvasElement().UpdateMemoryUsage();
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
EXPECT_EQ(800, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
// Creating a different accelerated image buffer
+ HTMLCanvasElement* anotherCanvas =
+ ToHTMLCanvasElement(GetDocument().getElementById("d"));
+ CanvasContextCreationAttributes attributes;
+ anotherCanvas->GetCanvasRenderingContext("2d", attributes);
auto fake_accelerate_surface2 =
std::make_unique<FakeAcceleratedImageBufferSurface>(IntSize(10, 5),
CanvasColorParams());
- std::unique_ptr<ImageBuffer> image_buffer2 =
- ImageBuffer::Create(std::move(fake_accelerate_surface2));
+ anotherCanvas->CreateImageBufferUsingSurfaceForTesting(
+ std::move(fake_accelerate_surface2));
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
EXPECT_EQ(1200, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(2u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(2u, GetGlobalAcceleratedContextCount());
// Tear down the first image buffer that resides in current canvas element
CanvasElement().SetSize(IntSize(20, 20));
Mock::VerifyAndClearExpectations(fake_accelerate_surface_ptr);
EXPECT_EQ(400, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
// Tear down the second image buffer
- image_buffer2.reset();
+ anotherCanvas->SetSize(IntSize(20, 20));
EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
}
TEST_F(CanvasRenderingContext2DTest, CanvasDisposedBeforeContext) {
@@ -945,7 +951,7 @@
CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(bridge));
EXPECT_TRUE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
EXPECT_EQ(720000, GetGlobalGPUMemoryUsage());
DummyExceptionStateForTesting exception_state;
@@ -957,7 +963,7 @@
EXPECT_FALSE(exception_state.HadException());
EXPECT_TRUE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
EXPECT_EQ(720000, GetGlobalGPUMemoryUsage());
}
@@ -967,11 +973,11 @@
EXPECT_FALSE(exception_state.HadException());
if (CanvasHeuristicParameters::kGPUReadbackForcesNoAcceleration) {
EXPECT_FALSE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
} else {
EXPECT_TRUE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
EXPECT_EQ(720000, GetGlobalGPUMemoryUsage());
}
}
@@ -1006,7 +1012,7 @@
CanvasElement().CreateImageBufferUsingSurfaceForTesting(std::move(bridge));
EXPECT_TRUE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
// 4 bytes per pixel * 2 buffers = 8
EXPECT_EQ(8 * dst_size * dst_size, GetGlobalGPUMemoryUsage());
sk_sp<SkSurface> sk_surface =
@@ -1022,11 +1028,11 @@
if (test_variant == kLargeTextureDisablesAcceleration) {
EXPECT_FALSE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
} else {
EXPECT_TRUE(CanvasElement().GetImageBuffer()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
EXPECT_EQ(8 * dst_size * dst_size, GetGlobalGPUMemoryUsage());
}
}
@@ -1046,19 +1052,19 @@
// pixel per buffer, and 2 is an estimate of num of gpu buffers required
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
EXPECT_EQ(800, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(1u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
context->fillRect(10, 10, 100, 100);
EXPECT_TRUE(CanvasElement().GetImageBuffer()->IsAccelerated());
- CanvasElement().GetImageBuffer()->DisableAcceleration();
+ CanvasElement().DisableAcceleration();
EXPECT_FALSE(CanvasElement().GetImageBuffer()->IsAccelerated());
context->fillRect(10, 10, 100, 100);
EXPECT_EQ(0, GetCurrentGPUMemoryUsage());
EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
- EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount());
+ EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
}
enum class ColorSpaceConversion : uint8_t {
diff --git a/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
index b3ca9e2..f4207d8 100644
--- a/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -197,12 +197,6 @@
void OffscreenCanvasRenderingContext2D::DisableDeferral(DisableDeferralReason) {
}
-AffineTransform OffscreenCanvasRenderingContext2D::BaseTransform() const {
- if (!HasImageBuffer())
- return AffineTransform(); // identity
- return GetImageBuffer()->BaseTransform();
-}
-
void OffscreenCanvasRenderingContext2D::DidDraw(const SkIRect& dirty_rect) {
dirty_rect_for_commit_.join(dirty_rect);
}
diff --git a/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
index e979c33c..c00b22d 100644
--- a/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -97,7 +97,6 @@
PaintCanvas* ExistingDrawingCanvas() const final;
void DisableDeferral(DisableDeferralReason) final;
- AffineTransform BaseTransform() const final;
void DidDraw(const SkIRect& dirty_rect) final; // overrides
// BaseRenderingContext2D and
// CanvasRenderingContext
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.cpp b/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.cpp
index 3b42c2a..0ac5223 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.cpp
@@ -58,11 +58,6 @@
return image_buffer_->Canvas();
}
-AffineTransform PaintRenderingContext2D::BaseTransform() const {
- DCHECK(image_buffer_);
- return image_buffer_->BaseTransform();
-}
-
void PaintRenderingContext2D::DidDraw(const SkIRect& dirty_rect) {
DCHECK(image_buffer_);
return image_buffer_->DidDraw(SkRect::Make(dirty_rect));
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h b/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h
index aa1d9e6..513c05d 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h
@@ -59,8 +59,6 @@
PaintCanvas* ExistingDrawingCanvas() const final;
void DisableDeferral(DisableDeferralReason) final {}
- AffineTransform BaseTransform() const final;
-
void DidDraw(const SkIRect& dirty_rect) final;
bool StateHasFilter() final;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index dcd06b0..3d7abab 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -7821,13 +7821,12 @@
CanvasRenderingContext::TraceWrappers(visitor);
}
-int WebGLRenderingContextBase::ExternallyAllocatedBytesPerPixel() {
+int WebGLRenderingContextBase::ExternallyAllocatedBufferCountPerPixel() {
if (isContextLost())
return 0;
- int bytes_per_pixel = 4;
- int total_bytes_per_pixel =
- bytes_per_pixel * 2; // WebGL's front and back color buffers.
+ int buffer_count = 1;
+ buffer_count *= 2; // WebGL's front and back color buffers.
int samples = GetDrawingBuffer() ? GetDrawingBuffer()->SampleCount() : 0;
Nullable<WebGLContextAttributes> attribs;
getContextAttributes(attribs);
@@ -7838,16 +7837,14 @@
if (attribs.Get().antialias() && samples > 0 &&
GetDrawingBuffer()->ExplicitResolveOfMultisampleData()) {
if (attribs.Get().depth() || attribs.Get().stencil())
- total_bytes_per_pixel +=
- samples * bytes_per_pixel; // depth/stencil multisample buffer
- total_bytes_per_pixel +=
- samples * bytes_per_pixel; // color multisample buffer
+ buffer_count += samples; // depth/stencil multisample buffer
+ buffer_count += samples; // color multisample buffer
} else if (attribs.Get().depth() || attribs.Get().stencil()) {
- total_bytes_per_pixel += bytes_per_pixel; // regular depth/stencil buffer
+ buffer_count += 1; // regular depth/stencil buffer
}
}
- return total_bytes_per_pixel;
+ return buffer_count;
}
DrawingBuffer* WebGLRenderingContextBase::GetDrawingBuffer() const {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
index 311b108..c991fd5 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -569,7 +569,7 @@
virtual void TraceWrappers(const ScriptWrappableVisitor*) const;
// Returns approximate gpu memory allocated per pixel.
- int ExternallyAllocatedBytesPerPixel() override;
+ int ExternallyAllocatedBufferCountPerPixel() override;
class TextureUnitState {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index fca1215..461ca53 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -863,6 +863,7 @@
"graphics/CanvasMetrics.h",
"graphics/CanvasResource.cpp",
"graphics/CanvasResource.h",
+ "graphics/CanvasResourceHost.h",
"graphics/CanvasResourceProvider.cpp",
"graphics/CanvasResourceProvider.h",
"graphics/Color.cpp",
@@ -928,7 +929,6 @@
"graphics/ImageAnimationPolicy.h",
"graphics/ImageBuffer.cpp",
"graphics/ImageBuffer.h",
- "graphics/ImageBufferClient.h",
"graphics/ImageBufferSurface.cpp",
"graphics/ImageBufferSurface.h",
"graphics/ImageDecodingStore.cpp",
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 296b9ff..519442d 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -62,8 +62,7 @@
Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size,
int msaa_sample_count,
AccelerationMode acceleration_mode,
- const CanvasColorParams& color_params,
- bool is_unit_test)
+ const CanvasColorParams& color_params)
: ImageBufferSurface(size, color_params),
logger_(WTF::WrapUnique(new Logger)),
weak_ptr_factory_(this),
@@ -77,11 +76,11 @@
is_deferral_enabled_(true),
software_rendering_while_hidden_(false),
acceleration_mode_(acceleration_mode),
- color_params_(color_params) {
+ color_params_(color_params),
+ resource_host_(nullptr) {
// Used by browser tests to detect the use of a Canvas2DLayerBridge.
TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation",
TRACE_EVENT_SCOPE_GLOBAL);
-
StartRecording();
Clear();
}
@@ -101,9 +100,10 @@
// and clip.
canvas->save();
- if (image_buffer_) {
- image_buffer_->ResetCanvas(canvas);
+ if (resource_host_) {
+ resource_host_->RestoreCanvasMatrixClipStack(canvas);
}
+
recording_pixel_count_ = 0;
}
@@ -229,8 +229,8 @@
layer_->ClearTexture();
// shouldBeDirectComposited() may have changed.
- if (image_buffer_)
- image_buffer_->SetNeedsCompositingUpdate();
+ if (resource_host_)
+ resource_host_->SetNeedsCompositingUpdate();
logger_->DidStartHibernating();
}
@@ -317,14 +317,16 @@
©_paint);
hibernation_image_.reset();
- if (image_buffer_) {
- image_buffer_->UpdateGPUMemoryUsage();
+ if (resource_host_) {
+ resource_host_->UpdateMemoryUsage();
- if (!is_deferral_enabled_)
- image_buffer_->ResetCanvas(resource_provider_->Canvas());
+ if (!is_deferral_enabled_) {
+ resource_host_->RestoreCanvasMatrixClipStack(
+ resource_provider_->Canvas());
+ }
// shouldBeDirectComposited() may have changed.
- image_buffer_->SetNeedsCompositingUpdate();
+ resource_host_->SetNeedsCompositingUpdate();
}
}
@@ -367,15 +369,12 @@
recorder_.reset();
// install the current matrix/clip stack onto the immediate canvas
GetOrCreateResourceProvider();
- if (image_buffer_ && resource_provider_)
- image_buffer_->ResetCanvas(resource_provider_->Canvas());
+ if (resource_host_ && resource_provider_)
+ resource_host_->RestoreCanvasMatrixClipStack(resource_provider_->Canvas());
}
void Canvas2DLayerBridge::SetImageBuffer(ImageBuffer* image_buffer) {
image_buffer_ = image_buffer;
- if (image_buffer_ && is_deferral_enabled_) {
- image_buffer_->ResetCanvas(recorder_->getRecordingCanvas());
- }
}
void Canvas2DLayerBridge::BeginDestruction() {
@@ -454,8 +453,9 @@
old_resource_provider->Snapshot()->PaintImageForCurrentFrame();
resource_provider_->Canvas()->drawImage(snapshot, 0, 0, ©_paint);
}
- if (image_buffer_ && !is_deferral_enabled_) {
- image_buffer_->ResetCanvas(resource_provider_->Canvas());
+ if (resource_host_ && !is_deferral_enabled_) {
+ resource_host_->RestoreCanvasMatrixClipStack(
+ resource_provider_->Canvas());
}
} else {
// New resource provider could not be created. Stay with old one.
@@ -504,8 +504,8 @@
canvas->drawImage(builder.TakePaintImage(), x, y, ©_paint);
canvas->save(); // intial save
- if (image_buffer_ && !is_deferral_enabled_) {
- image_buffer_->ResetCanvas(canvas);
+ if (resource_host_ && !is_deferral_enabled_) {
+ resource_host_->RestoreCanvasMatrixClipStack(canvas);
}
// We did not make a copy of the pixel data, so it needs to be consumed
@@ -564,8 +564,8 @@
resource_provider_->IsGpuContextLost()) {
context_lost_ = true;
ResetResourceProvider();
- if (image_buffer_)
- image_buffer_->NotifySurfaceInvalid();
+ if (resource_host_)
+ resource_host_->NotifySurfaceInvalid();
CanvasMetrics::CountCanvasContextUsage(
CanvasMetrics::kAccelerated2DCanvasGPUContextLost);
return false;
@@ -609,8 +609,9 @@
}
context_lost_ = false;
}
- if (image_buffer_)
- image_buffer_->UpdateGPUMemoryUsage();
+
+ if (resource_host_)
+ resource_host_->UpdateMemoryUsage();
return resource_provider_.get();
}
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
index 4125b6a..2996480 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
@@ -33,6 +33,7 @@
#include "cc/layers/texture_layer_client.h"
#include "platform/PlatformExport.h"
#include "platform/geometry/IntSize.h"
+#include "platform/graphics/CanvasResourceHost.h"
#include "platform/graphics/ImageBufferSurface.h"
#include "platform/graphics/paint/PaintRecorder.h"
#include "platform/wtf/Allocator.h"
@@ -79,8 +80,7 @@
Canvas2DLayerBridge(const IntSize&,
int msaa_sample_count,
AccelerationMode,
- const CanvasColorParams&,
- bool is_unit_test = false);
+ const CanvasColorParams&);
~Canvas2DLayerBridge() override;
@@ -111,6 +111,9 @@
void DontUseIdleSchedulingForTesting() {
dont_use_idle_scheduling_for_testing_ = true;
}
+ void SetCanvasResourceHost(CanvasResourceHost* host) {
+ resource_host_ = host;
+ }
void BeginDestruction();
void Hibernate();
@@ -193,6 +196,8 @@
AccelerationMode acceleration_mode_;
CanvasColorParams color_params_;
CheckedNumeric<int> recording_pixel_count_;
+
+ CanvasResourceHost* resource_host_;
};
} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
index 39049e0..d131bf4 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
@@ -36,6 +36,7 @@
#include "platform/CrossThreadFunctional.h"
#include "platform/WaitableEvent.h"
#include "platform/WebTaskRunner.h"
+#include "platform/graphics/CanvasResourceHost.h"
#include "platform/graphics/CanvasResourceProvider.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/StaticBitmapImage.h"
@@ -131,8 +132,8 @@
const IntSize& size,
Canvas2DLayerBridge::AccelerationMode acceleration_mode) {
std::unique_ptr<Canvas2DLayerBridge> bridge =
- WTF::WrapUnique(new Canvas2DLayerBridge(
- size, 0, acceleration_mode, CanvasColorParams(), IsUnitTest()));
+ WTF::WrapUnique(new Canvas2DLayerBridge(size, 0, acceleration_mode,
+ CanvasColorParams()));
bridge->DontUseIdleSchedulingForTesting();
return bridge;
}
@@ -146,7 +147,6 @@
WTF::Bind(factory, WTF::Unretained(&gl_)));
}
void TearDown() override { SharedGpuContext::ResetForTesting(); }
- bool IsUnitTest() { return true; }
protected:
MockGLES2InterfaceWithImageSupport gl_;
@@ -154,7 +154,7 @@
void FullLifecycleTest() {
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kDisableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
const GrGLTextureInfo* texture_info =
skia::GrBackendObjectToGrGLTextureInfo(
@@ -172,7 +172,7 @@
gl_.SetIsContextLost(true);
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
EXPECT_TRUE(bridge->IsValid());
EXPECT_FALSE(bridge->IsAccelerated());
}
@@ -182,7 +182,7 @@
// No fallback case.
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated());
scoped_refptr<StaticBitmapImage> snapshot = bridge->NewImageSnapshot(
@@ -198,7 +198,7 @@
->GetGrContext();
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated()); // We don't yet know that
// allocation will fail.
@@ -215,7 +215,7 @@
void NoDrawOnContextLostTest() {
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
EXPECT_TRUE(bridge->IsValid());
PaintFlags flags;
uint32_t gen_id = bridge->GetOrCreateResourceProvider()->ContentUniqueID();
@@ -237,7 +237,7 @@
void PrepareMailboxWhenContextIsLost() {
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
EXPECT_TRUE(bridge->IsAccelerated());
bridge->FinalizeFrame(); // Trigger the creation of a backing store
@@ -254,7 +254,7 @@
void PrepareMailboxWhenContextIsLostWithFailedRestore() {
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->GetOrCreateResourceProvider();
EXPECT_TRUE(bridge->IsValid());
@@ -305,7 +305,7 @@
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0,
Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->FinalizeFrame();
viz::TransferableResource resource;
std::unique_ptr<viz::SingleReleaseCallback> release_callback;
@@ -325,7 +325,7 @@
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0,
Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->FinalizeFrame();
bridge->PrepareTransferableResource(&resource, &release_callback);
// |bridge| goes out of scope and would normally be destroyed, but
@@ -345,7 +345,7 @@
{
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
PaintFlags flags;
bridge->Canvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot(
@@ -357,7 +357,7 @@
{
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
PaintFlags flags;
bridge->Canvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
scoped_refptr<StaticBitmapImage> image = bridge->NewImageSnapshot(
@@ -424,6 +424,14 @@
virtual ~MockImageBuffer() {}
};
+class MockCanvasResourceHost : public CanvasResourceHost {
+ public:
+ void NotifySurfaceInvalid() {}
+ void SetNeedsCompositingUpdate() {}
+ void UpdateMemoryUsage() {}
+ MOCK_CONST_METHOD1(RestoreCanvasMatrixClipStack, void(PaintCanvas*));
+};
+
void DrawSomething(Canvas2DLayerBridgePtr& bridge) {
bridge->DidDraw(FloatRect(0, 0, 1, 1));
bridge->FinalizeFrame();
@@ -440,7 +448,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -485,7 +493,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -533,15 +541,17 @@
#endif
{
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
+ MockCanvasResourceHost mock_host;
+ EXPECT_CALL(mock_host, RestoreCanvasMatrixClipStack(_)).Times(AnyNumber());
+
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
+
+ bridge->SetCanvasResourceHost(&mock_host);
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
bridge->DisableDeferral(kDisableDeferralReasonUnknown);
- MockImageBuffer mock_image_buffer;
- EXPECT_CALL(mock_image_buffer, ResetCanvas(_)).Times(AnyNumber());
- bridge->SetImageBuffer(&mock_image_buffer);
// Register an alternate Logger for tracking hibernation events
std::unique_ptr<MockLogger> mock_logger = WTF::WrapUnique(new MockLogger);
@@ -556,7 +566,7 @@
bridge->SetIsHidden(true);
platform->RunUntilIdle();
::testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- ::testing::Mock::VerifyAndClearExpectations(&mock_image_buffer);
+ ::testing::Mock::VerifyAndClearExpectations(&mock_host);
EXPECT_FALSE(bridge->IsAccelerated());
EXPECT_TRUE(bridge->IsHibernating());
EXPECT_TRUE(bridge->IsValid());
@@ -565,11 +575,11 @@
EXPECT_CALL(
*mock_logger_ptr,
ReportHibernationEvent(Canvas2DLayerBridge::kHibernationEndedNormally));
- EXPECT_CALL(mock_image_buffer, ResetCanvas(_))
+ EXPECT_CALL(mock_host, RestoreCanvasMatrixClipStack(_))
.Times(AtLeast(1)); // Because deferred rendering is disabled
bridge->SetIsHidden(false);
::testing::Mock::VerifyAndClearExpectations(mock_logger_ptr);
- ::testing::Mock::VerifyAndClearExpectations(&mock_image_buffer);
+ ::testing::Mock::VerifyAndClearExpectations(&mock_host);
EXPECT_TRUE(bridge->IsAccelerated());
EXPECT_FALSE(bridge->IsHibernating());
EXPECT_TRUE(bridge->IsValid());
@@ -584,7 +594,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -637,7 +647,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
MockImageBuffer mock_image_buffer;
@@ -697,7 +707,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -760,7 +770,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -798,7 +808,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -847,7 +857,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -880,7 +890,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -915,7 +925,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -951,7 +961,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -986,7 +996,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
bridge->DontUseIdleSchedulingForTesting();
DrawSomething(bridge);
@@ -1029,7 +1039,7 @@
ScopedTestingPlatformSupport<FakePlatformSupport> platform;
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
DrawSomething(bridge);
// Register an alternate Logger for tracking hibernation events
@@ -1086,7 +1096,7 @@
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
::testing::Mock::VerifyAndClearExpectations(&gl_);
@@ -1152,7 +1162,7 @@
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
::testing::Mock::VerifyAndClearExpectations(&gl_);
@@ -1213,7 +1223,7 @@
Canvas2DLayerBridgePtr bridge(WTF::WrapUnique(new Canvas2DLayerBridge(
IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting,
- CanvasColorParams(), IsUnitTest())));
+ CanvasColorParams())));
::testing::Mock::VerifyAndClearExpectations(&gl_);
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResourceHost.h b/third_party/WebKit/Source/platform/graphics/CanvasResourceHost.h
new file mode 100644
index 0000000..911e45dd5
--- /dev/null
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResourceHost.h
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CanvasResourceHost_h
+#define CanvasResourceHost_h
+
+#include "platform/PlatformExport.h"
+#include "platform/graphics/paint/PaintCanvas.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT CanvasResourceHost {
+ public:
+ virtual ~CanvasResourceHost() {}
+ virtual void NotifySurfaceInvalid() = 0;
+ virtual void SetNeedsCompositingUpdate() = 0;
+ virtual void RestoreCanvasMatrixClipStack(PaintCanvas*) const = 0;
+ virtual void UpdateMemoryUsage() = 0;
+};
+
+} // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
index c4d26cc..6f041c6 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.cpp
@@ -39,7 +39,6 @@
#include "platform/geometry/IntRect.h"
#include "platform/graphics/CanvasHeuristicParameters.h"
#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/ImageBufferClient.h"
#include "platform/graphics/RecordingImageBufferSurface.h"
#include "platform/graphics/StaticBitmapImage.h"
#include "platform/graphics/UnacceleratedImageBufferSurface.h"
@@ -51,7 +50,6 @@
#include "platform/image-encoders/ImageEncoder.h"
#include "platform/network/mime/MIMETypeRegistry.h"
#include "platform/runtime_enabled_features.h"
-#include "platform/wtf/CheckedNumeric.h"
#include "platform/wtf/MathExtras.h"
#include "platform/wtf/PtrUtil.h"
#include "platform/wtf/Vector.h"
@@ -92,24 +90,11 @@
ImageBuffer::ImageBuffer(std::unique_ptr<ImageBufferSurface> surface)
: weak_ptr_factory_(this),
snapshot_state_(kInitialSnapshotState),
- surface_(std::move(surface)),
- client_(nullptr),
- gpu_readback_invoked_in_current_frame_(false),
- gpu_readback_successive_frames_(0),
- gpu_memory_usage_(0) {
+ surface_(std::move(surface)) {
surface_->SetImageBuffer(this);
- UpdateGPUMemoryUsage();
}
-intptr_t ImageBuffer::global_gpu_memory_usage_ = 0;
-unsigned ImageBuffer::global_accelerated_image_buffer_count_ = 0;
-
ImageBuffer::~ImageBuffer() {
- if (gpu_memory_usage_) {
- DCHECK_GT(global_accelerated_image_buffer_count_, 0u);
- global_accelerated_image_buffer_count_--;
- }
- ImageBuffer::global_gpu_memory_usage_ -= gpu_memory_usage_;
surface_->SetImageBuffer(nullptr);
}
@@ -138,22 +123,6 @@
}
void ImageBuffer::FinalizeFrame() {
- if (IsAccelerated() &&
- CanvasHeuristicParameters::kGPUReadbackForcesNoAcceleration &&
- !RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled()) {
- if (gpu_readback_invoked_in_current_frame_) {
- gpu_readback_successive_frames_++;
- gpu_readback_invoked_in_current_frame_ = false;
- } else {
- gpu_readback_successive_frames_ = 0;
- }
-
- if (gpu_readback_successive_frames_ >=
- CanvasHeuristicParameters::kGPUReadbackMinSuccessiveFrames) {
- DisableAcceleration();
- }
- }
-
surface_->FinalizeFrame();
}
@@ -165,16 +134,6 @@
return surface_->IsValid() || surface_->Restore();
}
-void ImageBuffer::NotifySurfaceInvalid() {
- if (client_)
- client_->NotifySurfaceInvalid();
-}
-
-void ImageBuffer::ResetCanvas(PaintCanvas* canvas) const {
- if (client_)
- client_->RestoreCanvasMatrixClipStack(canvas);
-}
-
scoped_refptr<StaticBitmapImage> ImageBuffer::NewImageSnapshot(
AccelerationHint hint,
SnapshotReason reason) const {
@@ -311,7 +270,8 @@
}
bool ImageBuffer::GetImageData(const IntRect& rect,
- WTF::ArrayBufferContents& contents) const {
+ WTF::ArrayBufferContents& contents,
+ bool* is_gpu_readback_invoked) const {
uint8_t bytes_per_pixel = surface_->ColorParams().BytesPerPixel();
CheckedNumeric<int> data_size = bytes_per_pixel;
data_size *= rect.Width();
@@ -367,7 +327,9 @@
DCHECK(read_pixels_successful ||
!sk_image->bounds().intersect(SkIRect::MakeXYWH(
rect.X(), rect.Y(), info.width(), info.height())));
- gpu_readback_invoked_in_current_frame_ = true;
+ if (is_gpu_readback_invoked) {
+ *is_gpu_readback_invoked = true;
+ }
result.Transfer(contents);
return true;
}
@@ -428,47 +390,6 @@
surface_->WritePixels(info, src_addr, src_bytes_per_row, dest_x, dest_y);
}
-void ImageBuffer::UpdateGPUMemoryUsage() const {
- if (this->IsAccelerated()) {
- // If image buffer is accelerated, we should keep track of GPU memory usage.
- int gpu_buffer_count = 2;
- CheckedNumeric<intptr_t> checked_gpu_usage =
- surface_->ColorParams().BytesPerPixel() * gpu_buffer_count;
- checked_gpu_usage *= this->Size().Width();
- checked_gpu_usage *= this->Size().Height();
- intptr_t gpu_memory_usage =
- checked_gpu_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max());
-
- if (!gpu_memory_usage_) // was not accelerated before
- global_accelerated_image_buffer_count_++;
-
- global_gpu_memory_usage_ += (gpu_memory_usage - gpu_memory_usage_);
- gpu_memory_usage_ = gpu_memory_usage;
- } else if (gpu_memory_usage_) {
- // In case of switching from accelerated to non-accelerated mode,
- // the GPU memory usage needs to be updated too.
- DCHECK_GT(global_accelerated_image_buffer_count_, 0u);
- global_accelerated_image_buffer_count_--;
- global_gpu_memory_usage_ -= gpu_memory_usage_;
- gpu_memory_usage_ = 0;
-
- if (client_)
- client_->DidDisableAcceleration();
- }
-}
-
-void ImageBuffer::DisableAcceleration() {
- if (!IsAccelerated())
- return;
-
- // Create and configure a recording (unaccelerated) surface.
- std::unique_ptr<ImageBufferSurface> surface =
- WTF::WrapUnique(new RecordingImageBufferSurface(
- surface_->Size(), RecordingImageBufferSurface::kAllowFallback,
- surface_->ColorParams()));
- SetSurface(std::move(surface));
-}
-
void ImageBuffer::SetSurface(std::unique_ptr<ImageBufferSurface> surface) {
scoped_refptr<StaticBitmapImage> image =
surface_->NewImageSnapshot(kPreferNoAcceleration, kSnapshotReasonPaint);
@@ -491,16 +412,12 @@
}
surface->Canvas()->drawImage(image->PaintImageForCurrentFrame(), 0, 0);
surface->SetImageBuffer(this);
- if (client_)
- client_->RestoreCanvasMatrixClipStack(surface->Canvas());
surface_ = std::move(surface);
-
- UpdateGPUMemoryUsage();
}
-void ImageBuffer::SetNeedsCompositingUpdate() {
- if (client_)
- client_->SetNeedsCompositingUpdate();
+void ImageBuffer::OnCanvasDisposed() {
+ if (surface_)
+ surface_->SetCanvasResourceHost(nullptr);
}
bool ImageDataBuffer::EncodeImage(const String& mime_type,
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
index 216b2fa..4a26bed 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageBuffer.h
@@ -62,7 +62,6 @@
class DrawingBuffer;
class GraphicsContext;
-class ImageBufferClient;
class IntPoint;
class IntRect;
@@ -80,8 +79,6 @@
virtual ~ImageBuffer();
- void SetClient(ImageBufferClient* client) { client_ = client; }
-
static bool CanCreateImageBuffer(const IntSize&);
const IntSize& Size() const { return surface_->Size(); }
bool IsAccelerated() const { return surface_->IsAccelerated(); }
@@ -103,10 +100,6 @@
}
void SetIsHidden(bool hidden) { surface_->SetIsHidden(hidden); }
- // Called by subclasses of ImageBufferSurface to install a new canvas object.
- // Virtual for mocking
- virtual void ResetCanvas(PaintCanvas*) const;
-
PaintCanvas* Canvas() const;
void DisableDeferral(DisableDeferralReason) const;
@@ -116,14 +109,15 @@
void WillOverwriteCanvas() { surface_->WillOverwriteCanvas(); }
- bool GetImageData(const IntRect&, WTF::ArrayBufferContents&) const;
+ bool GetImageData(const IntRect&,
+ WTF::ArrayBufferContents&,
+ bool* is_gpu_readback_invoked = nullptr) const;
void PutByteArray(const unsigned char* source,
const IntSize& source_size,
const IntRect& source_rect,
const IntPoint& dest_point);
- AffineTransform BaseTransform() const { return AffineTransform(); }
WebLayer* PlatformLayer() const;
// Destroys the TEXTURE_2D binding for the active texture unit of the passed
@@ -140,8 +134,6 @@
bool CopyRenderingResultsFromDrawingBuffer(DrawingBuffer*,
SourceDrawingBuffer);
- void NotifySurfaceInvalid();
-
scoped_refptr<StaticBitmapImage> NewImageSnapshot(
AccelerationHint = kPreferNoAcceleration,
SnapshotReason = kSnapshotReasonUnknown) const;
@@ -150,17 +142,11 @@
void Draw(GraphicsContext&, const FloatRect&, const FloatRect*, SkBlendMode);
- void UpdateGPUMemoryUsage() const;
- static intptr_t GetGlobalGPUMemoryUsage() { return global_gpu_memory_usage_; }
- static unsigned GetGlobalAcceleratedImageBufferCount() {
- return global_accelerated_image_buffer_count_;
- }
- intptr_t GetGPUMemoryUsage() { return gpu_memory_usage_; }
-
- void DisableAcceleration();
void SetSurface(std::unique_ptr<ImageBufferSurface>);
- void SetNeedsCompositingUpdate();
+ // TODO(xlai): This function is an intermediate step making canvas element
+ // have reference to Canvas2DLayerBridge. See crbug.com/776806.
+ void OnCanvasDisposed();
WeakPtrFactory<ImageBuffer> weak_ptr_factory_;
@@ -175,14 +161,6 @@
};
mutable SnapshotState snapshot_state_;
std::unique_ptr<ImageBufferSurface> surface_;
- ImageBufferClient* client_;
-
- mutable bool gpu_readback_invoked_in_current_frame_;
- int gpu_readback_successive_frames_;
-
- mutable intptr_t gpu_memory_usage_;
- static intptr_t global_gpu_memory_usage_;
- static unsigned global_accelerated_image_buffer_count_;
};
struct ImageDataBuffer {
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBufferClient.h b/third_party/WebKit/Source/platform/graphics/ImageBufferClient.h
deleted file mode 100644
index 55b567b..0000000
--- a/third_party/WebKit/Source/platform/graphics/ImageBufferClient.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2014, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ImageBufferClient_h
-#define ImageBufferClient_h
-
-#include "platform/PlatformExport.h"
-#include "platform/graphics/paint/PaintCanvas.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT ImageBufferClient {
- public:
- virtual ~ImageBufferClient() {}
- virtual void NotifySurfaceInvalid() = 0;
- virtual void DidDisableAcceleration() = 0;
- virtual void RestoreCanvasMatrixClipStack(PaintCanvas*) const = 0;
- virtual void SetNeedsCompositingUpdate() = 0;
-};
-
-} // namespace blink
-
-#endif
diff --git a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
index a33328b..ac81313 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageBufferSurface.h
@@ -48,6 +48,7 @@
namespace blink {
+class CanvasResourceHost;
class FloatRect;
class GraphicsContext;
class ImageBuffer;
@@ -89,6 +90,7 @@
size_t row_bytes,
int x,
int y) = 0;
+ virtual void SetCanvasResourceHost(CanvasResourceHost*) {}
// May return nullptr if the surface is GPU-backed and the GPU context was
// lost.
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
index 955c1005..53fdbc2 100644
--- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
+++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp
@@ -32,7 +32,8 @@
frame_was_cleared_(true),
did_record_draw_commands_in_current_frame_(false),
current_frame_has_expensive_op_(false),
- previous_frame_has_expensive_op_(false) {
+ previous_frame_has_expensive_op_(false),
+ resource_host_(nullptr) {
InitializeCurrentFrame();
}
@@ -46,8 +47,8 @@
// and clip.
canvas->save();
- if (image_buffer_) {
- image_buffer_->ResetCanvas(canvas);
+ if (resource_host_) {
+ resource_host_->RestoreCanvasMatrixClipStack(canvas);
}
did_record_draw_commands_in_current_frame_ = false;
current_frame_has_expensive_op_ = false;
@@ -56,13 +57,6 @@
void RecordingImageBufferSurface::SetImageBuffer(ImageBuffer* image_buffer) {
image_buffer_ = image_buffer;
- if (current_frame_ && image_buffer_) {
- image_buffer_->ResetCanvas(current_frame_->getRecordingCanvas());
- }
- if (fallback_surface_) {
- DCHECK(fallback_surface_->IsValid());
- fallback_surface_->SetImageBuffer(image_buffer);
- }
}
bool RecordingImageBufferSurface::WritePixels(const SkImageInfo& orig_info,
@@ -102,8 +96,6 @@
if (!fallback_surface_->IsValid())
return;
- fallback_surface_->SetImageBuffer(image_buffer_);
-
if (previous_frame_) {
fallback_surface_->Canvas()->drawPicture(previous_frame_);
previous_frame_.reset();
@@ -116,8 +108,8 @@
current_frame_.reset();
}
- if (image_buffer_) {
- image_buffer_->ResetCanvas(fallback_surface_->Canvas());
+ if (resource_host_) {
+ resource_host_->RestoreCanvasMatrixClipStack(fallback_surface_->Canvas());
}
CanvasMetrics::CountCanvasContextUsage(
@@ -263,13 +255,6 @@
FallBackToRasterCanvas(fallback_reason);
}
-void RecordingImageBufferSurface::DoPaintInvalidation(
- const FloatRect& dirty_rect) {
- if (fallback_surface_) {
- fallback_surface_->DoPaintInvalidation(dirty_rect);
- }
-}
-
void RecordingImageBufferSurface::WillOverwriteCanvas() {
frame_was_cleared_ = true;
previous_frame_.reset();
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
index 52efa48..a22738a 100644
--- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
@@ -6,6 +6,7 @@
#define RecordingImageBufferSurface_h
#include <memory>
+#include "platform/graphics/CanvasResourceHost.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/ImageBufferSurface.h"
#include "platform/wtf/Allocator.h"
@@ -38,6 +39,9 @@
PaintCanvas* Canvas() override;
void DisableDeferral(DisableDeferralReason) override;
sk_sp<PaintRecord> GetRecord() override;
+ void SetCanvasResourceHost(CanvasResourceHost* host) {
+ resource_host_ = host;
+ }
void DidDraw(const FloatRect&) override;
bool IsValid() const override { return true; }
@@ -49,7 +53,6 @@
int y) override;
void WillOverwriteCanvas() override;
void FinalizeFrame() override;
- void DoPaintInvalidation(const FloatRect&) override;
void SetImageBuffer(ImageBuffer*) override;
scoped_refptr<StaticBitmapImage> NewImageSnapshot(AccelerationHint,
SnapshotReason) override;
@@ -120,6 +123,8 @@
bool did_record_draw_commands_in_current_frame_;
bool current_frame_has_expensive_op_;
bool previous_frame_has_expensive_op_;
+
+ CanvasResourceHost* resource_host_;
};
} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp
index 3b7e441..dc90243 100644
--- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp
@@ -9,7 +9,6 @@
#include "platform/WebTaskRunner.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/ImageBuffer.h"
-#include "platform/graphics/ImageBufferClient.h"
#include "platform/graphics/UnacceleratedImageBufferSurface.h"
#include "platform/graphics/paint/PaintCanvas.h"
#include "platform/graphics/paint/PaintRecord.h"
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContextTest.cpp b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContextTest.cpp
index 88c39a7..4706492 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContextTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContextTest.cpp
@@ -36,8 +36,6 @@
void TearDown() override { SharedGpuContext::ResetForTesting(); }
- bool IsUnitTest() { return true; }
-
GLES2InterfaceType gl_;
};
@@ -124,10 +122,10 @@
EXPECT_FALSE(SharedGpuContext::IsValidWithoutRestoring());
IntSize size(10, 10);
CanvasColorParams color_params;
- std::unique_ptr<Canvas2DLayerBridge> bridge = WTF::WrapUnique(
- new Canvas2DLayerBridge(size, 0, /*msaa sample count*/
- Canvas2DLayerBridge::kEnableAcceleration,
- color_params, IsUnitTest()));
+ std::unique_ptr<Canvas2DLayerBridge> bridge =
+ WTF::WrapUnique(new Canvas2DLayerBridge(
+ size, 0, /*msaa sample count*/
+ Canvas2DLayerBridge::kEnableAcceleration, color_params));
EXPECT_TRUE(bridge->IsAccelerated());
EXPECT_TRUE(SharedGpuContext::IsValidWithoutRestoring());
bridge->BeginDestruction();