blob: 3ff7454e191c8849644950b263cacc736c511feb [file] [log] [blame]
// Copyright 2015 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.
#include "core/page/PageOverlay.h"
#include <memory>
#include "core/exported/WebViewImpl.h"
#include "core/frame/FrameTestHelpers.h"
#include "core/frame/LocalFrameView.h"
#include "core/frame/WebLocalFrameImpl.h"
#include "platform/graphics/Color.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/paint/DrawingRecorder.h"
#include "platform/graphics/paint/PaintController.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCanvas.h"
#include "public/platform/WebThread.h"
#include "public/web/WebSettings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPaint.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Property;
namespace blink {
namespace {
static const int kViewportWidth = 800;
static const int kViewportHeight = 600;
// These unit tests cover both PageOverlay and PageOverlayList.
void EnableAcceleratedCompositing(WebSettings* settings) {
settings->SetAcceleratedCompositingEnabled(true);
}
void DisableAcceleratedCompositing(WebSettings* settings) {
settings->SetAcceleratedCompositingEnabled(false);
}
// PageOverlay that paints a solid color.
class SolidColorOverlay : public PageOverlay::Delegate {
public:
SolidColorOverlay(Color color) : color_(color) {}
void PaintPageOverlay(const PageOverlay& page_overlay,
GraphicsContext& graphics_context,
const WebSize& size) const override {
if (DrawingRecorder::UseCachedDrawingIfPossible(
graphics_context, page_overlay, DisplayItem::kPageOverlay))
return;
FloatRect rect(0, 0, size.width, size.height);
DrawingRecorder recorder(graphics_context, page_overlay,
DisplayItem::kPageOverlay);
graphics_context.FillRect(rect, color_);
}
private:
Color color_;
};
class PageOverlayTest : public ::testing::Test {
protected:
enum CompositingMode { kAcceleratedCompositing, kUnacceleratedCompositing };
void Initialize(CompositingMode compositing_mode) {
helper_.Initialize(nullptr /* webFrameClient */,
nullptr /* webViewClient */,
nullptr /* webWidgetClient */,
compositing_mode == kAcceleratedCompositing
? EnableAcceleratedCompositing
: DisableAcceleratedCompositing);
GetWebView()->Resize(WebSize(kViewportWidth, kViewportHeight));
GetWebView()->UpdateAllLifecyclePhases();
ASSERT_EQ(compositing_mode == kAcceleratedCompositing,
GetWebView()->IsAcceleratedCompositingActive());
}
WebViewImpl* GetWebView() const { return helper_.GetWebView(); }
std::unique_ptr<PageOverlay> CreateSolidYellowOverlay() {
return PageOverlay::Create(
GetWebView()->MainFrameImpl(),
std::make_unique<SolidColorOverlay>(SK_ColorYELLOW));
}
void SetViewportSize(const WebSize& size) { helper_.SetViewportSize(size); }
template <typename OverlayType>
void RunPageOverlayTestWithAcceleratedCompositing();
private:
FrameTestHelpers::WebViewHelper helper_;
};
template <bool (*getter)(), void (*setter)(bool)>
class RuntimeFeatureChange {
public:
RuntimeFeatureChange(bool new_value) : old_value_(getter()) {
setter(new_value);
}
~RuntimeFeatureChange() { setter(old_value_); }
private:
bool old_value_;
};
class MockPageOverlayCanvas : public SkCanvas {
public:
MockPageOverlayCanvas(int width, int height) : SkCanvas(width, height) {}
MOCK_METHOD2(onDrawRect, void(const SkRect&, const SkPaint&));
};
TEST_F(PageOverlayTest, PageOverlay_AcceleratedCompositing) {
Initialize(kAcceleratedCompositing);
SetViewportSize(WebSize(kViewportWidth, kViewportHeight));
std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay();
page_overlay->Update();
GetWebView()->UpdateAllLifecyclePhases();
// Ideally, we would get results from the compositor that showed that this
// page overlay actually winds up getting drawn on top of the rest.
// For now, we just check that the GraphicsLayer will draw the right thing.
MockPageOverlayCanvas canvas(kViewportWidth, kViewportHeight);
EXPECT_CALL(canvas, onDrawRect(_, _)).Times(AtLeast(0));
EXPECT_CALL(canvas,
onDrawRect(SkRect::MakeWH(kViewportWidth, kViewportHeight),
Property(&SkPaint::getColor, SK_ColorYELLOW)));
GraphicsLayer* graphics_layer = page_overlay->GetGraphicsLayer();
WebRect rect(0, 0, kViewportWidth, kViewportHeight);
// Paint the layer with a null canvas to get a display list, and then
// replay that onto the mock canvas for examination.
IntRect int_rect = rect;
graphics_layer->Paint(&int_rect);
canvas.drawPicture(
ToSkPicture(graphics_layer->CapturePaintRecord(), int_rect));
}
TEST_F(PageOverlayTest, PageOverlay_VisualRect) {
Initialize(kAcceleratedCompositing);
std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay();
page_overlay->Update();
GetWebView()->UpdateAllLifecyclePhases();
EXPECT_EQ(LayoutRect(0, 0, kViewportWidth, kViewportHeight),
page_overlay->VisualRect());
}
} // namespace
} // namespace blink