Commit 62ca7f7c authored by xlai's avatar xlai Committed by Commit Bot

Add unit test to verify RestoreCanvasMatrixClipStack occurs after drawImage


As a follow-up CL to the hot fix
https://chromium-review.googlesource.com/876528, this newly added unit test
verifies whether canvas restores its matrix clip stack after the image is drawn
from old canvas2d bridge to the new canvas2d bridge.

Bug: 803950
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I129525cad9835f415ac594351ba720d48c63979d
Reviewed-on: https://chromium-review.googlesource.com/888093
Commit-Queue: Olivia Lai <xlai@chromium.org>
Reviewed-by: default avatarJustin Novosad <junov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533058}
parent f84d86f1
......@@ -436,9 +436,16 @@ void HTMLCanvasElement::FinalizeFrame() {
did_notify_listeners_for_current_frame_ = false;
}
void HTMLCanvasElement::DisableAcceleration() {
void HTMLCanvasElement::DisableAcceleration(
std::unique_ptr<Canvas2DLayerBridge>
unaccelerated_bridge_used_for_testing) {
// Create and configure an unaccelerated Canvas2DLayerBridge.
std::unique_ptr<Canvas2DLayerBridge> bridge = CreateUnaccelerated2dBuffer();
std::unique_ptr<Canvas2DLayerBridge> bridge;
if (unaccelerated_bridge_used_for_testing) {
bridge = std::move(unaccelerated_bridge_used_for_testing);
} else {
bridge = CreateUnaccelerated2dBuffer();
}
if (bridge && canvas2d_bridge_) {
ReplaceExistingCanvas2DBuffer(std::move(bridge));
......@@ -1542,10 +1549,11 @@ void HTMLCanvasElement::ReplaceExistingCanvas2DBuffer(
// functional.
if (!image)
return;
new_buffer->Canvas()->drawImage(image->PaintImageForCurrentFrame(), 0, 0);
new_buffer->DrawFullImage(image->PaintImageForCurrentFrame());
}
RestoreCanvasMatrixClipStack(new_buffer->Canvas());
new_buffer->DidRestoreCanvasMatrixClipStack(new_buffer->Canvas());
canvas2d_bridge_ = std::move(new_buffer);
}
......
......@@ -205,7 +205,8 @@ class CORE_EXPORT HTMLCanvasElement final
void SetNeedsCompositingUpdate() override;
void UpdateMemoryUsage() override;
void DisableAcceleration();
void DisableAcceleration(std::unique_ptr<Canvas2DLayerBridge>
unaccelerated_bridge_used_for_testing = nullptr);
// ImageBitmapSource implementation
IntSize BitmapSourceSize() const override;
......
......@@ -25,6 +25,7 @@
#include "platform/graphics/Canvas2DLayerBridge.h"
#include "platform/graphics/CanvasHeuristicParameters.h"
#include "platform/graphics/ColorCorrectionTestUtils.h"
#include "platform/graphics/GraphicsTypes.h"
#include "platform/graphics/StaticBitmapImage.h"
#include "platform/graphics/gpu/SharedGpuContext.h"
#include "platform/graphics/test/FakeGLES2Interface.h"
......@@ -42,6 +43,8 @@
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSwizzle.h"
using ::testing::_;
using ::testing::InSequence;
using ::testing::Mock;
namespace blink {
......@@ -259,18 +262,21 @@ std::unique_ptr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge(
//============================================================================
class FakeAcceleratedImageBufferSurface : public Canvas2DLayerBridge {
class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge {
public:
FakeAcceleratedImageBufferSurface(const IntSize& size,
CanvasColorParams color_params)
FakeCanvas2DLayerBridge(const IntSize& size,
CanvasColorParams color_params,
AccelerationHint hint)
: Canvas2DLayerBridge(size, 0, kDisableAcceleration, color_params),
is_accelerated_(true) {}
~FakeAcceleratedImageBufferSurface() override = default;
is_accelerated_(hint != kPreferNoAcceleration) {}
~FakeCanvas2DLayerBridge() override = default;
bool IsAccelerated() const override { return is_accelerated_; }
void SetIsAccelerated(bool is_accelerated) {
if (is_accelerated != is_accelerated_)
is_accelerated_ = is_accelerated;
}
MOCK_METHOD1(DrawFullImage, void(const PaintImage& image));
MOCK_METHOD1(DidRestoreCanvasMatrixClipStack, void(PaintCanvas*));
private:
bool is_accelerated_;
......@@ -547,10 +553,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
CreateContext(kNonOpaque);
IntSize size(10, 10);
std::unique_ptr<FakeAcceleratedImageBufferSurface> fake_accelerate_surface =
std::make_unique<FakeAcceleratedImageBufferSurface>(size,
CanvasColorParams());
FakeAcceleratedImageBufferSurface* fake_accelerate_surface_ptr =
std::unique_ptr<FakeCanvas2DLayerBridge> fake_accelerate_surface =
std::make_unique<FakeCanvas2DLayerBridge>(size, CanvasColorParams(),
kPreferAcceleration);
FakeCanvas2DLayerBridge* fake_accelerate_surface_ptr =
fake_accelerate_surface.get();
CanvasElement().CreateImageBufferUsingSurfaceForTesting(
std::move(fake_accelerate_surface), size);
......@@ -580,9 +586,8 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
CanvasContextCreationAttributes attributes;
anotherCanvas->GetCanvasRenderingContext("2d", attributes);
IntSize size2(10, 5);
auto fake_accelerate_surface2 =
std::make_unique<FakeAcceleratedImageBufferSurface>(size2,
CanvasColorParams());
auto fake_accelerate_surface2 = std::make_unique<FakeCanvas2DLayerBridge>(
size2, CanvasColorParams(), kPreferAcceleration);
anotherCanvas->CreateImageBufferUsingSurfaceForTesting(
std::move(fake_accelerate_surface2), size2);
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
......@@ -733,13 +738,12 @@ TEST_F(CanvasRenderingContext2DTest, MAYBE_TextureUploadHeuristics) {
}
}
TEST_F(CanvasRenderingContext2DTest, DisableAcceleration) {
TEST_F(CanvasRenderingContext2DTest, DisableAcceleration_UpdateGPUMemoryUsage) {
CreateContext(kNonOpaque);
IntSize size(10, 10);
auto fake_accelerate_surface =
std::make_unique<FakeAcceleratedImageBufferSurface>(size,
CanvasColorParams());
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
size, CanvasColorParams(), kPreferAcceleration);
CanvasElement().CreateImageBufferUsingSurfaceForTesting(
std::move(fake_accelerate_surface), size);
CanvasRenderingContext2D* context = Context2d();
......@@ -763,6 +767,36 @@ TEST_F(CanvasRenderingContext2DTest, DisableAcceleration) {
EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
}
TEST_F(CanvasRenderingContext2DTest,
DisableAcceleration_RestoreCanvasMatrixClipStack) {
// This tests verifies whether the RestoreCanvasMatrixClipStack happens after
// PaintCanvas is drawn from old 2d bridge to new 2d bridge.
InSequence s;
CreateContext(kNonOpaque);
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
size, CanvasColorParams(), kPreferAcceleration);
CanvasElement().CreateImageBufferUsingSurfaceForTesting(
std::move(fake_accelerate_surface), size);
auto fake_deaccelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
size, CanvasColorParams(), kPreferNoAcceleration);
PaintCanvas* paint_canvas_ptr = fake_deaccelerate_surface->Canvas();
FakeCanvas2DLayerBridge* surface_ptr = fake_deaccelerate_surface.get();
EXPECT_CALL(*fake_deaccelerate_surface, DrawFullImage(_)).Times(1);
EXPECT_CALL(*fake_deaccelerate_surface,
DidRestoreCanvasMatrixClipStack(paint_canvas_ptr))
.Times(1);
EXPECT_TRUE(CanvasElement().Canvas2DBuffer()->IsAccelerated());
CanvasElement().DisableAcceleration(std::move(fake_deaccelerate_surface));
EXPECT_FALSE(CanvasElement().Canvas2DBuffer()->IsAccelerated());
Mock::VerifyAndClearExpectations(surface_ptr);
}
enum class ColorSpaceConversion : uint8_t {
NONE = 0,
DEFAULT_COLOR_CORRECTED = 1,
......
......@@ -472,6 +472,10 @@ void Canvas2DLayerBridge::SetIsHidden(bool hidden) {
}
}
void Canvas2DLayerBridge::DrawFullImage(const cc::PaintImage& image) {
Canvas()->drawImage(image, 0, 0);
}
bool Canvas2DLayerBridge::WritePixels(const SkImageInfo& orig_info,
const void* pixels,
size_t row_bytes,
......
......@@ -96,13 +96,17 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
void DoPaintInvalidation(const FloatRect& dirty_rect);
WebLayer* Layer();
bool Restore();
virtual void WillOverwriteCanvas(); // virtual for unit testing
void DisableDeferral(DisableDeferralReason);
void SetFilterQuality(SkFilterQuality);
// virtual for unit testing
virtual void WillOverwriteCanvas();
virtual void DrawFullImage(const cc::PaintImage&);
virtual void DidRestoreCanvasMatrixClipStack(cc::PaintCanvas*) {}
virtual bool IsAccelerated() const;
PaintCanvas* Canvas();
bool IsValid() const;
virtual bool IsAccelerated() const; // virtual for unit testing
bool WritePixels(const SkImageInfo&,
const void* pixels,
size_t row_bytes,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment