1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "web/PageOverlay.h"
8 #include "core/frame/FrameView.h"
9 #include "core/layout/LayoutView.h"
10 #include "platform/graphics/Color.h"
11 #include "platform/graphics/GraphicsContext.h"
12 #include "platform/graphics/paint/DisplayItemList.h"
13 #include "platform/graphics/paint/DrawingRecorder.h"
14 #include "public/platform/Platform.h"
15 #include "public/platform/WebCanvas.h"
16 #include "public/platform/WebThread.h"
17 #include "public/web/WebSettings.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "third_party/skia/include/core/SkCanvas.h"
20 #include "third_party/skia/include/core/SkColor.h"
21 #include "third_party/skia/include/core/SkPaint.h"
22 #include "web/WebGraphicsContextImpl.h"
23 #include "web/WebLocalFrameImpl.h"
24 #include "web/WebViewImpl.h"
25 #include "web/tests/FrameTestHelpers.h"
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
30 using testing::AtLeast
;
31 using testing::Property
;
36 static const int viewportWidth
= 800;
37 static const int viewportHeight
= 600;
39 // These unit tests cover both PageOverlay and PageOverlayList.
41 void enableAcceleratedCompositing(WebSettings
* settings
)
43 settings
->setAcceleratedCompositingEnabled(true);
46 void disableAcceleratedCompositing(WebSettings
* settings
)
48 settings
->setAcceleratedCompositingEnabled(false);
51 class PageOverlayTest
: public ::testing::Test
{
53 enum CompositingMode
{ AcceleratedCompositing
, UnacceleratedCompositing
};
55 void initialize(CompositingMode compositingMode
)
58 false /* enableJavascript */, nullptr /* webFrameClient */, nullptr /* webViewClient */,
59 compositingMode
== AcceleratedCompositing
? enableAcceleratedCompositing
: disableAcceleratedCompositing
);
60 webViewImpl()->resize(WebSize(viewportWidth
, viewportHeight
));
61 webViewImpl()->layout();
62 ASSERT_EQ(compositingMode
== AcceleratedCompositing
, webViewImpl()->isAcceleratedCompositingActive());
65 WebViewImpl
* webViewImpl() const { return m_helper
.webViewImpl(); }
67 template <typename OverlayType
>
68 void runPageOverlayTestWithAcceleratedCompositing();
71 FrameTestHelpers::WebViewHelper m_helper
;
74 // PageOverlay that uses a WebCanvas to draw a solid color.
75 class SimpleCanvasOverlay
: public PageOverlay::Delegate
{
77 SimpleCanvasOverlay(SkColor color
) : m_color(color
) { }
79 void paintPageOverlay(WebGraphicsContext
* context
, const WebSize
& size
) override
81 WebFloatRect
rect(0, 0, size
.width
, size
.height
);
82 WebCanvas
* canvas
= context
->beginDrawing(rect
);
84 paint
.setColor(m_color
);
85 paint
.setStyle(SkPaint::kFill_Style
);
86 canvas
->drawRectCoords(0, 0, size
.width
, size
.height
, paint
);
87 context
->endDrawing();
94 // PageOverlay that uses the underlying blink::GraphicsContext to paint a
96 class PrivateGraphicsContextOverlay
: public PageOverlay::Delegate
{
98 PrivateGraphicsContextOverlay(Color color
) : m_color(color
) { }
100 void paintPageOverlay(WebGraphicsContext
* context
, const WebSize
& size
) override
102 GraphicsContext
& graphicsContext
= toWebGraphicsContextImpl(context
)->graphicsContext();
103 if (DrawingRecorder::useCachedDrawingIfPossible(graphicsContext
, *this, DisplayItem::PageOverlay
))
105 FloatRect
rect(0, 0, size
.width
, size
.height
);
106 DrawingRecorder
drawingRecorder(graphicsContext
, *this, DisplayItem::PageOverlay
, rect
);
107 graphicsContext
.fillRect(rect
, m_color
);
110 DisplayItemClient
displayItemClient() const { return toDisplayItemClient(this); }
111 String
debugName() const { return "PrivateGraphicsContextOverlay"; }
117 template <bool(*getter
)(), void(*setter
)(bool)>
118 class RuntimeFeatureChange
{
120 RuntimeFeatureChange(bool newValue
) : m_oldValue(getter()) { setter(newValue
); }
121 ~RuntimeFeatureChange() { setter(m_oldValue
); }
126 class MockCanvas
: public SkCanvas
{
128 MockCanvas(int width
, int height
) : SkCanvas(width
, height
) { }
129 MOCK_METHOD2(onDrawRect
, void(const SkRect
&, const SkPaint
&));
132 template <typename OverlayType
>
133 void PageOverlayTest::runPageOverlayTestWithAcceleratedCompositing()
135 initialize(AcceleratedCompositing
);
136 webViewImpl()->layerTreeView()->setViewportSize(WebSize(viewportWidth
, viewportHeight
));
138 OwnPtr
<PageOverlay
> pageOverlay
= PageOverlay::create(webViewImpl(), new OverlayType(SK_ColorYELLOW
));
139 pageOverlay
->update();
140 webViewImpl()->layout();
142 // Ideally, we would get results from the compositor that showed that this
143 // page overlay actually winds up getting drawn on top of the rest.
144 // For now, we just check that the GraphicsLayer will draw the right thing.
146 MockCanvas
canvas(viewportWidth
, viewportHeight
);
147 EXPECT_CALL(canvas
, onDrawRect(_
, _
)).Times(AtLeast(0));
148 EXPECT_CALL(canvas
, onDrawRect(SkRect::MakeWH(viewportWidth
, viewportHeight
), Property(&SkPaint::getColor
, SK_ColorYELLOW
)));
150 GraphicsLayer
* graphicsLayer
= pageOverlay
->graphicsLayer();
151 WebRect
rect(0, 0, viewportWidth
, viewportHeight
);
153 // Paint the layer with a null canvas to get a display list, and then
154 // replay that onto the mock canvas for examination.
155 GraphicsContext
graphicsContext(graphicsLayer
->displayItemList());
156 graphicsLayer
->paint(graphicsContext
, rect
);
158 graphicsContext
.beginRecording(IntRect(rect
));
159 graphicsLayer
->displayItemList()->commitNewDisplayItemsAndReplay(graphicsContext
);
160 graphicsContext
.endRecording()->playback(&canvas
);
163 TEST_F(PageOverlayTest
, SimpleCanvasOverlay_AcceleratedCompositing
)
165 runPageOverlayTestWithAcceleratedCompositing
<SimpleCanvasOverlay
>();
168 TEST_F(PageOverlayTest
, PrivateGraphicsContextOverlay_AcceleratedCompositing
)
170 runPageOverlayTestWithAcceleratedCompositing
<PrivateGraphicsContextOverlay
>();