Commit 0dcf9135 authored by Dominik Laskowski's avatar Dominik Laskowski Committed by Commit Bot

exo: Use cc::Region for damage and input regions

This CL cleans up verbose Skia calls in anticipation of more
operations on regions in a future CL. It also fixes a no-op
due to calling SkRegion::intersects instead of SkRegion::op
with kIntersect_Op.

Bug: b:67384524
Test: exo_unittests
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: Ic6059c3e844831ebe5053ded74096e5b0ff86bf8
Reviewed-on: https://chromium-review.googlesource.com/794373
Commit-Queue: Dominik Laskowski <domlaskowski@chromium.org>
Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520192}
parent 5a591913
......@@ -15,6 +15,8 @@ namespace cc {
Region::Region() {
}
Region::Region(const SkRegion& region) : skregion_(region) {}
Region::Region(const Region& region)
: skregion_(region.skregion_) {
}
......@@ -52,6 +54,10 @@ int Region::GetRegionComplexity() const {
return skregion_.computeRegionComplexity();
}
void Region::GetBoundaryPath(SkPath* path) const {
skregion_.getBoundaryPath(path);
}
bool Region::Contains(const gfx::Point& point) const {
return skregion_.contains(point.x(), point.y());
}
......
......@@ -13,6 +13,8 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/skia_util.h"
class SkPath;
namespace base {
class Value;
namespace trace_event {
......@@ -26,6 +28,7 @@ class SimpleEnclosedRegion;
class CC_BASE_EXPORT Region {
public:
Region();
explicit Region(const SkRegion& region);
Region(const Region& region);
Region(const gfx::Rect& rect); // NOLINT(runtime/explicit)
~Region();
......@@ -37,6 +40,7 @@ class CC_BASE_EXPORT Region {
void Clear();
bool IsEmpty() const;
int GetRegionComplexity() const;
void GetBoundaryPath(SkPath* path) const;
bool Contains(const gfx::Point& point) const;
bool Contains(const gfx::Rect& rect) const;
......
......@@ -623,8 +623,7 @@ TEST_F(ShellSurfaceTest, ModalWindowDefaultActive) {
std::unique_ptr<Buffer> desktop_buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(desktop_size)));
surface->Attach(desktop_buffer.get());
surface->SetInputRegion(
SkRegion(gfx::RectToSkIRect(gfx::Rect(10, 10, 100, 100))));
surface->SetInputRegion(gfx::Rect(10, 10, 100, 100));
ASSERT_FALSE(shell_surface->GetWidget());
shell_surface->SetSystemModal(true);
surface->Commit();
......@@ -642,7 +641,7 @@ TEST_F(ShellSurfaceTest, UpdateModalWindow) {
std::unique_ptr<Buffer> desktop_buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(desktop_size)));
surface->Attach(desktop_buffer.get());
surface->SetInputRegion(SkRegion());
surface->SetInputRegion(cc::Region());
surface->Commit();
EXPECT_FALSE(ash::ShellPort::Get()->IsSystemModalWindowOpen());
......@@ -671,8 +670,7 @@ TEST_F(ShellSurfaceTest, UpdateModalWindow) {
EXPECT_FALSE(shell_surface->GetWidget()->IsActive());
// Setting input regions won't make it modal either.
surface->SetInputRegion(
SkRegion(gfx::RectToSkIRect(gfx::Rect(10, 10, 100, 100))));
surface->SetInputRegion(gfx::Rect(10, 10, 100, 100));
surface->Commit();
EXPECT_FALSE(ash::ShellPort::Get()->IsSystemModalWindowOpen());
EXPECT_FALSE(shell_surface->GetWidget()->IsActive());
......@@ -710,7 +708,7 @@ TEST_F(ShellSurfaceTest, ModalWindowSetSystemModalBeforeCommit) {
std::unique_ptr<Buffer> desktop_buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(desktop_size)));
surface->Attach(desktop_buffer.get());
surface->SetInputRegion(SkRegion());
surface->SetInputRegion(cc::Region());
// Set SetSystemModal before any commit happens. Widget is not created at
// this time.
......
......@@ -43,7 +43,6 @@
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform_util.h"
#include "ui/views/widget/widget.h"
......@@ -238,7 +237,7 @@ void Surface::Attach(Buffer* buffer) {
void Surface::Damage(const gfx::Rect& damage) {
TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString());
pending_damage_.op(gfx::RectToSkIRect(damage), SkRegion::kUnion_Op);
pending_damage_.Union(damage);
}
void Surface::RequestFrameCallback(const FrameCallback& callback) {
......@@ -254,16 +253,14 @@ void Surface::RequestPresentationCallback(
pending_presentation_callbacks_.push_back(callback);
}
void Surface::SetOpaqueRegion(const SkRegion& region) {
TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region",
gfx::SkIRectToRect(region.getBounds()).ToString());
void Surface::SetOpaqueRegion(const cc::Region& region) {
TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", region.ToString());
pending_state_.opaque_region = region;
}
void Surface::SetInputRegion(const SkRegion& region) {
TRACE_EVENT1("exo", "Surface::SetInputRegion", "region",
gfx::SkIRectToRect(region.getBounds()).ToString());
void Surface::SetInputRegion(const cc::Region& region) {
TRACE_EVENT1("exo", "Surface::SetInputRegion", "region", region.ToString());
pending_state_.input_region = region;
}
......@@ -474,7 +471,7 @@ void Surface::CommitSurfaceHierarchy(bool synchronized) {
pending_state_.only_visible_on_secure_output = false;
window_->SetEventTargetingPolicy(
state_.input_region.isEmpty()
state_.input_region.IsEmpty()
? ui::mojom::EventTargetingPolicy::DESCENDANTS_ONLY
: ui::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
......@@ -522,16 +519,15 @@ void Surface::CommitSurfaceHierarchy(bool synchronized) {
sub_surfaces_changed_ = false;
}
SkIRect output_rect =
SkIRect::MakeWH(content_size_.width(), content_size_.height());
gfx::Rect output_rect(content_size_);
if (needs_full_damage) {
damage_.setRect(output_rect);
damage_ = output_rect;
} else {
// pending_damage_ is in Surface coordinates.
damage_.swap(pending_damage_);
damage_.intersects(output_rect);
damage_.Swap(&pending_damage_);
damage_.Intersect(output_rect);
}
pending_damage_.setEmpty();
pending_damage_.Clear();
}
surface_hierarchy_content_bounds_ = gfx::Rect(content_size_);
......@@ -595,34 +591,31 @@ bool Surface::IsSynchronized() const {
}
gfx::Rect Surface::GetHitTestBounds() const {
SkIRect bounds = state_.input_region.getBounds();
if (!bounds.intersect(gfx::RectToSkIRect(gfx::Rect(content_size_))))
return gfx::Rect();
return gfx::SkIRectToRect(bounds);
gfx::Rect bounds(content_size_);
bounds.Intersect(state_.input_region.bounds());
return bounds;
}
bool Surface::HitTestRect(const gfx::Rect& rect) const {
if (HasHitTestMask())
return state_.input_region.intersects(gfx::RectToSkIRect(rect));
return state_.input_region.Intersects(rect);
return rect.Intersects(gfx::Rect(content_size_));
}
bool Surface::HasHitTestMask() const {
return !state_.input_region.contains(
gfx::RectToSkIRect(gfx::Rect(content_size_)));
return !state_.input_region.Contains(gfx::Rect(content_size_));
}
void Surface::GetHitTestMask(gfx::Path* mask) const {
state_.input_region.getBoundaryPath(mask);
state_.input_region.GetBoundaryPath(mask);
}
std::unique_ptr<aura::WindowTargeter::HitTestRects>
Surface::GetHitTestShapeRects() const {
auto rects = std::make_unique<aura::WindowTargeter::HitTestRects>();
SkRegion::Iterator it(state_.input_region);
for (const SkIRect& rect = it.rect(); !it.done(); it.next())
rects->push_back(gfx::SkIRectToRect(rect));
for (cc::Region::Iterator it(state_.input_region); it.has_rect(); it.next())
rects->push_back(it.rect());
return rects;
}
......@@ -691,14 +684,13 @@ void Surface::SurfaceHierarchyResourcesLost() {
bool Surface::FillsBoundsOpaquely() const {
return !current_resource_has_alpha_ ||
state_.blend_mode == SkBlendMode::kSrc ||
state_.opaque_region.contains(
gfx::RectToSkIRect(gfx::Rect(content_size_)));
state_.opaque_region.Contains(gfx::Rect(content_size_));
}
////////////////////////////////////////////////////////////////////////////////
// Buffer, private:
Surface::State::State() : input_region(SkIRect::MakeLargest()) {}
Surface::State::State() : input_region(SkRegion(SkIRect::MakeLargest())) {}
Surface::State::~State() = default;
......@@ -806,13 +798,13 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
// Surface bounds are in DIPs, but |damage_rect| and |output_rect| are in
// pixels, so we need to scale by the |device_scale_factor|.
gfx::Rect damage_rect = gfx::SkIRectToRect(damage_.getBounds());
gfx::Rect damage_rect = damage_.bounds();
if (!damage_rect.IsEmpty()) {
// Outset damage by 1 DIP to as damage is in surface coordinate space and
// client might not be aware of |device_scale_factor| and the
// scaling/filtering it requires.
damage_rect.Inset(-1, -1);
damage_rect.Offset(origin.x(), origin.y());
damage_rect += origin.OffsetFromOrigin();
damage_rect.Intersect(output_rect);
render_pass->damage_rect.Union(
gfx::ConvertRectToPixel(device_scale_factor, damage_rect));
......@@ -836,9 +828,9 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
quad_to_target_transform.ConcatTransform(
gfx::Transform(viewport_to_target_matrix));
bool are_contents_opaque =
!current_resource_has_alpha_ || state_.blend_mode == SkBlendMode::kSrc ||
state_.opaque_region.contains(gfx::RectToSkIRect(output_rect));
bool are_contents_opaque = !current_resource_has_alpha_ ||
state_.blend_mode == SkBlendMode::kSrc ||
state_.opaque_region.Contains(output_rect);
viz::SharedQuadState* quad_state =
render_pass->CreateAndAppendSharedQuadState();
......
......@@ -14,12 +14,12 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "cc/base/region.h"
#include "components/exo/layer_tree_frame_sink_holder.h"
#include "components/exo/surface_delegate.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/aura/window.h"
#include "ui/aura/window_targeter.h"
#include "ui/gfx/geometry/rect.h"
......@@ -95,11 +95,11 @@ class Surface final : public ui::PropertyHandler {
void RequestPresentationCallback(const PresentationCallback& callback);
// This sets the region of the surface that contains opaque content.
void SetOpaqueRegion(const SkRegion& region);
void SetOpaqueRegion(const cc::Region& region);
// This sets the region of the surface that can receive pointer and touch
// events.
void SetInputRegion(const SkRegion& region);
void SetInputRegion(const cc::Region& region);
// This sets the scaling factor used to interpret the contents of the buffer
// attached to the surface. Note that if the scale is larger than 1, then you
......@@ -235,7 +235,7 @@ class Surface final : public ui::PropertyHandler {
bool FillsBoundsOpaquely() const;
bool HasPendingDamageForTesting(const gfx::Rect& damage) const {
return pending_damage_.contains(gfx::RectToSkIRect(damage));
return pending_damage_.Contains(damage);
}
private:
......@@ -246,8 +246,8 @@ class Surface final : public ui::PropertyHandler {
bool operator==(const State& other);
bool operator!=(const State& other) { return !(*this == other); }
SkRegion opaque_region;
SkRegion input_region;
cc::Region opaque_region;
cc::Region input_region;
float buffer_scale = 1.0f;
Transform buffer_transform = Transform::NORMAL;
gfx::Size viewport;
......@@ -318,11 +318,11 @@ class Surface final : public ui::PropertyHandler {
BufferAttachment pending_buffer_;
// The damage region to schedule paint for when Commit() is called.
SkRegion pending_damage_;
cc::Region pending_damage_;
// The damage region which will be used by
// AppendSurfaceHierarchyContentsToFrame() to generate frame.
SkRegion damage_;
cc::Region damage_;
// These lists contains the callbacks to notify the client when it is a good
// time to start producing a new frame. These callbacks move to
......
......@@ -191,7 +191,7 @@ TEST_P(SurfaceTest, SetOpaqueRegion) {
// Setting an opaque region that contains the buffer size doesn't require
// draw with blending.
surface->SetOpaqueRegion(SkRegion(SkIRect::MakeWH(256, 256)));
surface->SetOpaqueRegion(gfx::Rect(256, 256));
surface->Commit();
RunAllPendingInMessageLoop();
......@@ -208,7 +208,7 @@ TEST_P(SurfaceTest, SetOpaqueRegion) {
}
// Setting an empty opaque region requires draw with blending.
surface->SetOpaqueRegion(SkRegion(SkIRect::MakeEmpty()));
surface->SetOpaqueRegion(gfx::Rect());
surface->Commit();
RunAllPendingInMessageLoop();
......@@ -260,7 +260,7 @@ TEST_P(SurfaceTest, SetInputRegion) {
{
// Setting a non-empty input region should succeed.
surface->SetInputRegion(SkRegion(SkIRect::MakeWH(256, 256)));
surface->SetInputRegion(gfx::Rect(256, 256));
surface->Commit();
std::unique_ptr<std::vector<gfx::Rect>> rects =
surface->GetHitTestShapeRects();
......@@ -273,7 +273,7 @@ TEST_P(SurfaceTest, SetInputRegion) {
{
// Setting an empty input region should succeed.
surface->SetInputRegion(SkRegion(SkIRect::MakeEmpty()));
surface->SetInputRegion(gfx::Rect());
surface->Commit();
// The input region doesn't contain the surface, so we need hit test mask.
......@@ -284,7 +284,7 @@ TEST_P(SurfaceTest, SetInputRegion) {
{
// Setting an input region which contains the surface.
surface->SetInputRegion(SkRegion(SkIRect::MakeWH(512, 512)));
surface->SetInputRegion(gfx::Rect(512, 512));
surface->Commit();
// The input region contains the surface, so we don't need hit test mask.
......@@ -292,13 +292,13 @@ TEST_P(SurfaceTest, SetInputRegion) {
}
{
SkRegion region(SkIRect::MakeWH(512, 512));
region.op(SkIRect::MakeXYWH(0, 64, 64, 64), SkRegion::kDifference_Op);
region.op(SkIRect::MakeXYWH(88, 88, 12, 55), SkRegion::kDifference_Op);
region.op(SkIRect::MakeXYWH(100, 0, 33, 66), SkRegion::kDifference_Op);
cc::Region region = gfx::Rect(512, 512);
region.Subtract(gfx::Rect(0, 64, 64, 64));
region.Subtract(gfx::Rect(88, 88, 12, 55));
region.Subtract(gfx::Rect(100, 0, 33, 66));
// Setting a non-rectangle input region should succeed.
surface->SetInputRegion(SkRegion(region));
surface->SetInputRegion(region);
surface->Commit();
// The input region doesn't contain the surface, so we need hit test mask.
......@@ -306,9 +306,9 @@ TEST_P(SurfaceTest, SetInputRegion) {
auto rects = surface->GetHitTestShapeRects();
ASSERT_EQ(10u, rects->size());
SkRegion result(SkIRect::MakeEmpty());
cc::Region result;
for (const auto& r : *rects)
result.op(gfx::RectToSkIRect(r), SkRegion::kUnion_Op);
result.Union(r);
ASSERT_EQ(result, region);
}
}
......
......@@ -351,17 +351,17 @@ void surface_frame(wl_client* client,
void surface_set_opaque_region(wl_client* client,
wl_resource* resource,
wl_resource* region_resource) {
GetUserDataAs<Surface>(resource)->SetOpaqueRegion(
region_resource ? *GetUserDataAs<SkRegion>(region_resource)
: SkRegion(SkIRect::MakeEmpty()));
SkRegion region = region_resource ? *GetUserDataAs<SkRegion>(region_resource)
: SkRegion(SkIRect::MakeEmpty());
GetUserDataAs<Surface>(resource)->SetOpaqueRegion(cc::Region(region));
}
void surface_set_input_region(wl_client* client,
wl_resource* resource,
wl_resource* region_resource) {
GetUserDataAs<Surface>(resource)->SetInputRegion(
region_resource ? *GetUserDataAs<SkRegion>(region_resource)
: SkRegion(SkIRect::MakeLargest()));
SkRegion region = region_resource ? *GetUserDataAs<SkRegion>(region_resource)
: SkRegion(SkIRect::MakeLargest());
GetUserDataAs<Surface>(resource)->SetInputRegion(cc::Region(region));
}
void surface_commit(wl_client* client, wl_resource* resource) {
......
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