blob: 08ce4c6159a05e91994e9b8eb5a5eb01b5b8b4ed [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 "third_party/blink/renderer/core/page/page_overlay.h"
#include <memory>
#include "base/time/time.h"
#include "cc/paint/paint_canvas.h"
#include "cc/trees/layer_tree_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.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.
// 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 IntSize& 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:
PageOverlayTest() {
helper_.Initialize(nullptr /* web_frame_client */,
nullptr /* web_view_client */,
nullptr /* web_widget_client */);
GetWebView()->Resize(WebSize(kViewportWidth, kViewportHeight));
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
WebWidget::LifecycleUpdateReason::kTest);
}
WebViewImpl* GetWebView() const { return helper_.GetWebView(); }
std::unique_ptr<PageOverlay> CreateSolidYellowOverlay() {
return PageOverlay::Create(
GetWebView()->MainFrameImpl()->GetFrame(),
std::make_unique<SolidColorOverlay>(SK_ColorYELLOW));
}
void SetViewportSize(const WebSize& size) {
content::LayerTreeView* layer_tree_view = helper_.GetLayerTreeView();
layer_tree_view->SetViewportSizeAndScale(
static_cast<gfx::Size>(size), /*device_scale_factor=*/1.f,
layer_tree_view->layer_tree_host()
->local_surface_id_allocation_from_parent());
}
template <typename OverlayType>
void RunPageOverlayTestWithAcceleratedCompositing();
private:
frame_test_helpers::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) {
SetViewportSize(WebSize(kViewportWidth, kViewportHeight));
std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay();
page_overlay->Update();
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
WebWidget::LifecycleUpdateReason::kTest);
GraphicsLayer* graphics_layer = page_overlay->GetGraphicsLayer();
WebRect rect(0, 0, kViewportWidth, kViewportHeight);
IntRect int_rect = rect;
graphics_layer->Paint(&int_rect);
// 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)));
canvas.drawPicture(
ToSkPicture(graphics_layer->CapturePaintRecord(), int_rect));
}
TEST_F(PageOverlayTest, PageOverlay_VisualRect) {
std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay();
page_overlay->Update();
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
WebWidget::LifecycleUpdateReason::kTest);
EXPECT_EQ(LayoutRect(0, 0, kViewportWidth, kViewportHeight),
page_overlay->VisualRect());
}
} // namespace
} // namespace blink