[3/5] Add translated rasterization support for RasterBuffer & below
This CL implements the muscle of transformed rasterization. RasterBuffer now
accepts a translation in addition to a scale factor when rasterizing into a
backing.
Arbitrary raster transformation is not planned for near future. Thus only
implementing scale & translate which already helps many common cases.
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel
Review-Url: https://codereview.chromium.org/2563743004
Cr-Commit-Position: refs/heads/master@{#461673}
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index 0144636..c41d38e 100644
--- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -17,6 +17,7 @@
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
#include "ui/gfx/geometry/rect.h"
namespace cc {
@@ -52,9 +53,10 @@
bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect.width(),
content_rect.height()));
SkCanvas canvas(bitmap);
- raster_source->PlaybackToCanvas(&canvas, gfx::ColorSpace(), content_rect,
- content_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster_source->PlaybackToCanvas(
+ &canvas, gfx::ColorSpace(), content_rect, content_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
timer.NextLap();
} while (!timer.HasTimeLimitExpired());
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc
index 8bd1e381..95fa085 100644
--- a/cc/output/software_renderer.cc
+++ b/cc/output/software_renderer.cc
@@ -29,6 +29,7 @@
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkLayerRasterizer.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
@@ -362,11 +363,15 @@
disable_image_filtering);
quad->raster_source->PlaybackToCanvas(
&filtered_canvas, canvas_color_space, quad->content_rect,
- quad->content_rect, quad->contents_scale, playback_settings);
+ quad->content_rect,
+ gfx::AxisTransform2d(quad->contents_scale, gfx::Vector2dF()),
+ playback_settings);
} else {
quad->raster_source->PlaybackToCanvas(
current_canvas_, canvas_color_space, quad->content_rect,
- quad->content_rect, quad->contents_scale, playback_settings);
+ quad->content_rect,
+ gfx::AxisTransform2d(quad->contents_scale, gfx::Vector2dF()),
+ playback_settings);
}
}
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc
index a69ad18..470e6e03 100644
--- a/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -40,7 +40,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) override {
TRACE_EVENT0("cc", "BitmapRasterBuffer::Playback");
gfx::Rect playback_rect = raster_full_rect;
@@ -53,7 +53,7 @@
size_t stride = 0u;
RasterBufferProvider::PlaybackToMemory(
lock_.sk_bitmap().getPixels(), resource_->format(), resource_->size(),
- stride, raster_source, raster_full_rect, playback_rect, scale,
+ stride, raster_source, raster_full_rect, playback_rect, transform,
lock_.color_space_for_raster(), playback_settings);
}
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc
index 1cc36f18..de489ff 100644
--- a/cc/raster/gpu_raster_buffer_provider.cc
+++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -34,7 +34,7 @@
const gfx::Size& resource_size,
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
ContextProvider* context_provider,
ResourceProvider::ScopedWriteLockGL* resource_lock,
@@ -79,7 +79,7 @@
raster_source->PlaybackToCanvas(
sk_surface->getCanvas(), resource_lock->color_space_for_raster(),
- raster_full_rect, playback_rect, scale, playback_settings);
+ raster_full_rect, playback_rect, transform, playback_settings);
}
} // namespace
@@ -105,13 +105,13 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) {
TRACE_EVENT0("cc", "GpuRasterBuffer::Playback");
client_->PlaybackOnWorkerThread(&lock_, sync_token_,
resource_has_previous_content_, raster_source,
raster_full_rect, raster_dirty_rect,
- new_content_id, scale, playback_settings);
+ new_content_id, transform, playback_settings);
}
GpuRasterBufferProvider::GpuRasterBufferProvider(
@@ -252,7 +252,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) {
ContextProvider::ScopedContextLock scoped_context(worker_context_provider_);
gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL();
@@ -269,7 +269,7 @@
RasterizeSource(raster_source, resource_has_previous_content,
resource_lock->size(), raster_full_rect, raster_dirty_rect,
- scale, playback_settings, worker_context_provider_,
+ transform, playback_settings, worker_context_provider_,
resource_lock, async_worker_context_enabled_,
use_distance_field_text_, msaa_sample_count_);
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h
index 248a72f9..0777db2 100644
--- a/cc/raster/gpu_raster_buffer_provider.h
+++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -51,7 +51,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings);
private:
@@ -70,7 +70,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) override;
void set_sync_token(const gpu::SyncToken& sync_token) {
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc
index 214dfa9..abc63e46 100644
--- a/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -57,12 +57,12 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) {
TRACE_EVENT0("cc", "OneCopyRasterBuffer::Playback");
client_->PlaybackAndCopyOnWorkerThread(
resource_, &lock_, sync_token_, raster_source, raster_full_rect,
- raster_dirty_rect, scale, playback_settings, previous_content_id_,
+ raster_dirty_rect, transform, playback_settings, previous_content_id_,
new_content_id);
}
@@ -215,7 +215,7 @@
const RasterSource* raster_source,
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
uint64_t previous_content_id,
uint64_t new_content_id) {
@@ -236,7 +236,7 @@
PlaybackToStagingBuffer(
staging_buffer.get(), resource, raster_source, raster_full_rect,
- raster_dirty_rect, scale, resource_lock->color_space_for_raster(),
+ raster_dirty_rect, transform, resource_lock->color_space_for_raster(),
playback_settings, previous_content_id, new_content_id);
CopyOnWorkerThread(staging_buffer.get(), resource_lock, sync_token,
@@ -251,7 +251,7 @@
const RasterSource* raster_source,
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const gfx::ColorSpace& dst_color_space,
const RasterSource::PlaybackSettings& playback_settings,
uint64_t previous_content_id,
@@ -301,7 +301,7 @@
RasterBufferProvider::PlaybackToMemory(
buffer->memory(0), resource->format(), staging_buffer->size,
buffer->stride(0), raster_source, raster_full_rect, playback_rect,
- scale, dst_color_space, playback_settings);
+ transform, dst_color_space, playback_settings);
buffer->Unmap();
staging_buffer->content_id = new_content_id;
}
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h
index f757e59..5d82849 100644
--- a/cc/raster/one_copy_raster_buffer_provider.h
+++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -56,7 +56,7 @@
const RasterSource* raster_source,
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
uint64_t previous_content_id,
uint64_t new_content_id);
@@ -77,7 +77,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) override;
void set_sync_token(const gpu::SyncToken& sync_token) {
@@ -101,7 +101,7 @@
const RasterSource* raster_source,
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const gfx::ColorSpace& dst_color_space,
const RasterSource::PlaybackSettings& playback_settings,
uint64_t previous_content_id,
diff --git a/cc/raster/raster_buffer.h b/cc/raster/raster_buffer.h
index d045a70..0de76b3 100644
--- a/cc/raster/raster_buffer.h
+++ b/cc/raster/raster_buffer.h
@@ -11,6 +11,10 @@
#include "cc/raster/raster_source.h"
#include "ui/gfx/geometry/rect.h"
+namespace gfx {
+class AxisTransform2d;
+} // namespace gfx
+
namespace cc {
class CC_EXPORT RasterBuffer {
@@ -23,7 +27,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) = 0;
};
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc
index bb49ae0..fe76a0a 100644
--- a/cc/raster/raster_buffer_provider.cc
+++ b/cc/raster/raster_buffer_provider.cc
@@ -13,6 +13,7 @@
#include "cc/resources/resource_format_utils.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
namespace cc {
@@ -52,7 +53,7 @@
const RasterSource* raster_source,
const gfx::Rect& canvas_bitmap_rect,
const gfx::Rect& canvas_playback_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const gfx::ColorSpace& target_color_space,
const RasterSource::PlaybackSettings& playback_settings) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
@@ -83,7 +84,7 @@
SkSurface::MakeRasterDirect(info, memory, stride, &surface_props);
raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space,
canvas_bitmap_rect, canvas_playback_rect,
- scale, playback_settings);
+ transform, playback_settings);
return;
}
case RGBA_4444:
@@ -93,7 +94,7 @@
// playback rect passed to PlaybackToCanvas. crbug.com/519070
raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space,
canvas_bitmap_rect, canvas_bitmap_rect,
- scale, playback_settings);
+ transform, playback_settings);
if (format == ETC1) {
TRACE_EVENT0("cc",
diff --git a/cc/raster/raster_buffer_provider.h b/cc/raster/raster_buffer_provider.h
index 011cd1d..40611df 100644
--- a/cc/raster/raster_buffer_provider.h
+++ b/cc/raster/raster_buffer_provider.h
@@ -38,7 +38,7 @@
const RasterSource* raster_source,
const gfx::Rect& canvas_bitmap_rect,
const gfx::Rect& canvas_playback_rect,
- float scale,
+ const gfx::AxisTransform2d& transform,
const gfx::ColorSpace& target_color_space,
const RasterSource::PlaybackSettings& playback_settings);
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc
index 8e35a3d..ea4cdff 100644
--- a/cc/raster/raster_buffer_provider_unittest.cc
+++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -38,6 +38,7 @@
#include "cc/tiles/tile_task_manager.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
namespace cc {
namespace {
@@ -83,7 +84,8 @@
uint64_t new_content_id = 0;
raster_buffer_->Playback(raster_source_.get(), gfx::Rect(1, 1),
- gfx::Rect(1, 1), new_content_id, 1.f, settings);
+ gfx::Rect(1, 1), new_content_id,
+ gfx::AxisTransform2d(), settings);
}
// Overridden from TileTask:
diff --git a/cc/raster/raster_source.cc b/cc/raster/raster_source.cc
index 43d7792..796b7980 100644
--- a/cc/raster/raster_source.cc
+++ b/cc/raster/raster_source.cc
@@ -18,6 +18,7 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace cc {
@@ -60,12 +61,13 @@
RasterSource::~RasterSource() {}
-void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas,
- const gfx::ColorSpace& canvas_color_space,
- const gfx::Rect& canvas_bitmap_rect,
- const gfx::Rect& canvas_playback_rect,
- float raster_scale,
- const PlaybackSettings& settings) const {
+void RasterSource::PlaybackToCanvas(
+ SkCanvas* raster_canvas,
+ const gfx::ColorSpace& canvas_color_space,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
+ const gfx::AxisTransform2d& raster_transform,
+ const PlaybackSettings& settings) const {
SkIRect raster_bounds = gfx::RectToSkIRect(canvas_bitmap_rect);
if (!canvas_playback_rect.IsEmpty() &&
!raster_bounds.intersect(gfx::RectToSkIRect(canvas_playback_rect)))
@@ -76,7 +78,9 @@
raster_canvas->save();
raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds));
- raster_canvas->scale(raster_scale, raster_scale);
+ raster_canvas->translate(raster_transform.translation().x(),
+ raster_transform.translation().y());
+ raster_canvas->scale(raster_transform.scale(), raster_transform.scale());
PlaybackToCanvas(raster_canvas, canvas_color_space, settings);
raster_canvas->restore();
}
diff --git a/cc/raster/raster_source.h b/cc/raster/raster_source.h
index ff9d0f2..b6292c5 100644
--- a/cc/raster/raster_source.h
+++ b/cc/raster/raster_source.h
@@ -19,6 +19,10 @@
#include "third_party/skia/include/core/SkPicture.h"
#include "ui/gfx/color_space.h"
+namespace gfx {
+class AxisTransform2d;
+} // namespace gfx
+
namespace cc {
class DisplayItemList;
class DrawImage;
@@ -54,12 +58,20 @@
const RecordingSource* other,
bool can_use_lcd_text);
- // TODO(trchen): Deprecated.
+ // Helper function to apply a few common operations before passing the canvas
+ // to the shorter version. This is useful for rastering into tiles.
+ // canvas is expected to be backed by a tile, with a default state.
+ // raster_transform will be applied to the display list, rastering the list
+ // into the "content space".
+ // canvas_bitmap_rect defines the extent of the tile in the content space,
+ // i.e. contents in the rect will be cropped and translated onto the canvas.
+ // canvas_playback_rect can be used to replay only part of the recording in,
+ // the content space, so only a sub-rect of the tile gets rastered.
void PlaybackToCanvas(SkCanvas* canvas,
const gfx::ColorSpace& canvas_color_space,
const gfx::Rect& canvas_bitmap_rect,
const gfx::Rect& canvas_playback_rect,
- float contents_scale,
+ const gfx::AxisTransform2d& raster_transform,
const PlaybackSettings& settings) const;
// Raster this RasterSource into the given canvas. Canvas states such as
diff --git a/cc/raster/raster_source_unittest.cc b/cc/raster/raster_source_unittest.cc
index 4ec8c94..e1510781 100644
--- a/cc/raster/raster_source_unittest.cc
+++ b/cc/raster/raster_source_unittest.cc
@@ -15,6 +15,7 @@
#include "third_party/skia/include/core/SkPixelRef.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkShader.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -290,9 +291,10 @@
SkCanvas canvas(bitmap);
canvas.clear(SK_ColorTRANSPARENT);
- raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), canvas_rect,
- canvas_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster->PlaybackToCanvas(
+ &canvas, ColorSpaceForTesting(), canvas_rect, canvas_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
int num_pixels = bitmap.width() * bitmap.height();
@@ -342,9 +344,10 @@
// Playback the full rect which should make everything white.
gfx::Rect raster_full_rect(content_bounds);
gfx::Rect playback_rect(content_bounds);
- raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect,
- playback_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster->PlaybackToCanvas(
+ &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
{
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
@@ -374,9 +377,10 @@
// We're going to playback from "everything is black" into a smaller area,
// that touches the edge pixels of the recording.
playback_rect.Inset(1, 2, 0, 1);
- raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect,
- playback_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster->PlaybackToCanvas(
+ &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
int num_black = 0;
@@ -439,9 +443,10 @@
// Playback the full rect which should make everything light gray (alpha=10).
gfx::Rect raster_full_rect(content_bounds);
gfx::Rect playback_rect(content_bounds);
- raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect,
- playback_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster->PlaybackToCanvas(
+ &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
{
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
@@ -479,9 +484,10 @@
// darker white background rectangle.
playback_rect =
gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale));
- raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), raster_full_rect,
- playback_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster->PlaybackToCanvas(
+ &canvas, ColorSpaceForTesting(), raster_full_rect, playback_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
// Test that the whole playback_rect was cleared and repainted with new alpha.
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
@@ -520,9 +526,10 @@
bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
SkCanvas canvas(bitmap);
- raster->PlaybackToCanvas(&canvas, ColorSpaceForTesting(), canvas_rect,
- canvas_rect, contents_scale,
- RasterSource::PlaybackSettings());
+ raster->PlaybackToCanvas(
+ &canvas, ColorSpaceForTesting(), canvas_rect, canvas_rect,
+ gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()),
+ RasterSource::PlaybackSettings());
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
int num_pixels = bitmap.width() * bitmap.height();
@@ -595,8 +602,8 @@
settings.playback_to_shared_canvas = true;
settings.use_image_hijack_canvas = true;
raster_source->PlaybackToCanvas(&canvas, ColorSpaceForTesting(),
- gfx::Rect(size), gfx::Rect(size), 1.f,
- settings);
+ gfx::Rect(size), gfx::Rect(size),
+ gfx::AxisTransform2d(), settings);
EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0));
EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(49, 0));
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc
index 27d6c88..85db2c46 100644
--- a/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -34,7 +34,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) override {
TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback");
gfx::GpuMemoryBuffer* buffer = lock_.GetGpuMemoryBuffer();
@@ -52,7 +52,7 @@
RasterBufferProvider::PlaybackToMemory(
buffer->memory(0), resource_->format(), resource_->size(),
buffer->stride(0), raster_source, raster_full_rect, raster_full_rect,
- scale, lock_.color_space_for_raster(), playback_settings);
+ transform, lock_.color_space_for_raster(), playback_settings);
buffer->Unmap();
}
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index 9916918..bb8e450 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -29,6 +29,7 @@
#include "cc/raster/task_category.h"
#include "cc/tiles/frame_viewer_instrumentation.h"
#include "cc/tiles/tile.h"
+#include "ui/gfx/geometry/axis_transform2d.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace cc {
@@ -126,9 +127,10 @@
DCHECK(raster_source_);
- raster_buffer_->Playback(raster_source_.get(), content_rect_,
- invalid_content_rect_, new_content_id_,
- raster_scale_, playback_settings_);
+ raster_buffer_->Playback(
+ raster_source_.get(), content_rect_, invalid_content_rect_,
+ new_content_id_, gfx::AxisTransform2d(raster_scale_, gfx::Vector2dF()),
+ playback_settings_);
}
// Overridden from TileTask:
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index 39da63a0..3675241 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -1988,7 +1988,7 @@
const gfx::Rect& raster_full_rect,
const gfx::Rect& raster_dirty_rect,
uint64_t new_content_id,
- float scale,
+ const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings) override {}
};
};
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 77856da..a534b0e 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -626,6 +626,7 @@
"color_utils_unittest.cc",
"font_fallback_mac_unittest.cc",
"font_list_unittest.cc",
+ "geometry/axis_transform2d_unittest.cc",
"geometry/box_unittest.cc",
"geometry/cubic_bezier_unittest.cc",
"geometry/insets_unittest.cc",
diff --git a/ui/gfx/geometry/BUILD.gn b/ui/gfx/geometry/BUILD.gn
index 59690a2..0bf2db1 100644
--- a/ui/gfx/geometry/BUILD.gn
+++ b/ui/gfx/geometry/BUILD.gn
@@ -5,6 +5,8 @@
component("geometry") {
sources = [
"../gfx_export.h",
+ "axis_transform2d.cc",
+ "axis_transform2d.h",
"box_f.cc",
"box_f.h",
"cubic_bezier.cc",
diff --git a/ui/gfx/geometry/axis_transform2d.cc b/ui/gfx/geometry/axis_transform2d.cc
new file mode 100644
index 0000000..5b7d86a4
--- /dev/null
+++ b/ui/gfx/geometry/axis_transform2d.cc
@@ -0,0 +1,16 @@
+// Copyright 2013 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 "ui/gfx/geometry/axis_transform2d.h"
+
+#include "base/strings/stringprintf.h"
+
+namespace gfx {
+
+std::string AxisTransform2d::ToString() const {
+ return base::StringPrintf("[%f, %s]", scale_,
+ translation_.ToString().c_str());
+}
+
+} // namespace gfx
\ No newline at end of file
diff --git a/ui/gfx/geometry/axis_transform2d.h b/ui/gfx/geometry/axis_transform2d.h
new file mode 100644
index 0000000..1829bf6
--- /dev/null
+++ b/ui/gfx/geometry/axis_transform2d.h
@@ -0,0 +1,138 @@
+// Copyright (c) 2017 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.
+
+#ifndef UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_
+#define UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_
+
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
+#include "ui/gfx/gfx_export.h"
+
+namespace gfx {
+
+// This class implements the subset of 2D linear transforms that only
+// translation and uniform scaling are allowed.
+// Internally this is stored as a scalar pre-scale factor, and a vector
+// for post-translation. The class constructor and member accessor follows
+// the same convention.
+class GFX_EXPORT AxisTransform2d {
+ public:
+ constexpr AxisTransform2d() = default;
+ constexpr AxisTransform2d(float scale, const Vector2dF& translation)
+ : scale_(scale), translation_(translation) {}
+
+ bool operator==(const AxisTransform2d& other) const {
+ return scale_ == other.scale_ && translation_ == other.translation_;
+ }
+ bool operator!=(const AxisTransform2d& other) const {
+ return !(*this == other);
+ }
+
+ void PreScale(float scale) { scale_ *= scale; }
+ void PostScale(float scale) {
+ scale_ *= scale;
+ translation_.Scale(scale);
+ }
+ void PreTranslate(const Vector2dF& translation) {
+ translation_ += ScaleVector2d(translation, scale_);
+ }
+ void PostTranslate(const Vector2dF& translation) {
+ translation_ += translation;
+ }
+
+ void PreConcat(const AxisTransform2d& pre) {
+ PreTranslate(pre.translation_);
+ PreScale(pre.scale_);
+ }
+ void PostConcat(const AxisTransform2d& post) {
+ PostScale(post.scale_);
+ PostTranslate(post.translation_);
+ }
+
+ void Invert() {
+ DCHECK(scale_);
+ scale_ = 1.f / scale_;
+ translation_.Scale(-scale_);
+ }
+
+ PointF MapPoint(const PointF& p) const {
+ return ScalePoint(p, scale_) + translation_;
+ }
+ PointF InverseMapPoint(const PointF& p) const {
+ return ScalePoint(p - translation_, 1.f / scale_);
+ }
+
+ RectF MapRect(const RectF& r) const {
+ DCHECK(scale_ >= 0.f);
+ return ScaleRect(r, scale_) + translation_;
+ }
+ RectF InverseMapRect(const RectF& r) const {
+ DCHECK(scale_ > 0.f);
+ return ScaleRect(r - translation_, 1.f / scale_);
+ }
+
+ float scale() const { return scale_; }
+ const Vector2dF& translation() const { return translation_; }
+
+ std::string ToString() const;
+
+ private:
+ // Scale is applied before translation, i.e.
+ // this->Transform(p) == scale_ * p + translation_
+ float scale_ = 1.f;
+ Vector2dF translation_;
+};
+
+static inline AxisTransform2d PreScaleAxisTransform2d(const AxisTransform2d& t,
+ float scale) {
+ AxisTransform2d result(t);
+ result.PreScale(scale);
+ return result;
+}
+
+static inline AxisTransform2d PostScaleAxisTransform2d(const AxisTransform2d& t,
+ float scale) {
+ AxisTransform2d result(t);
+ result.PostScale(scale);
+ return result;
+}
+
+static inline AxisTransform2d PreTranslateAxisTransform2d(
+ const AxisTransform2d& t,
+ const Vector2dF& translation) {
+ AxisTransform2d result(t);
+ result.PreTranslate(translation);
+ return result;
+}
+
+static inline AxisTransform2d PostTranslateAxisTransform2d(
+ const AxisTransform2d& t,
+ const Vector2dF& translation) {
+ AxisTransform2d result(t);
+ result.PostTranslate(translation);
+ return result;
+}
+
+static inline AxisTransform2d ConcatAxisTransform2d(
+ const AxisTransform2d& post,
+ const AxisTransform2d& pre) {
+ AxisTransform2d result(post);
+ result.PreConcat(pre);
+ return result;
+}
+
+static inline AxisTransform2d InvertAxisTransform2d(const AxisTransform2d& t) {
+ AxisTransform2d result = t;
+ result.Invert();
+ return result;
+}
+
+// This is declared here for use in gtest-based unit tests but is defined in
+// the //ui/gfx:test_support target. Depend on that to use this in your unit
+// test. This should not be used in production code - call ToString() instead.
+void PrintTo(const AxisTransform2d&, ::std::ostream* os);
+
+} // namespace gfx
+
+#endif // UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_
diff --git a/ui/gfx/geometry/axis_transform2d_unittest.cc b/ui/gfx/geometry/axis_transform2d_unittest.cc
new file mode 100644
index 0000000..b132c69
--- /dev/null
+++ b/ui/gfx/geometry/axis_transform2d_unittest.cc
@@ -0,0 +1,91 @@
+// Copyright 2017 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 "ui/gfx/geometry/axis_transform2d.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/test/gfx_util.h"
+
+namespace gfx {
+namespace {
+
+TEST(AxisTransform2dTest, Mapping) {
+ AxisTransform2d t(1.25f, Vector2dF(3.75f, 55.f));
+
+ PointF p(150.f, 100.f);
+ EXPECT_EQ(PointF(191.25f, 180.f), t.MapPoint(p));
+ EXPECT_POINTF_EQ(PointF(117.f, 36.f), t.InverseMapPoint(p));
+
+ RectF r(150.f, 100.f, 22.5f, 37.5f);
+ EXPECT_EQ(RectF(191.25f, 180.f, 28.125f, 46.875f), t.MapRect(r));
+ EXPECT_RECTF_EQ(RectF(117.f, 36.f, 18.f, 30.f), t.InverseMapRect(r));
+}
+
+TEST(AxisTransform2dTest, Scaling) {
+ {
+ AxisTransform2d t(1.25f, Vector2dF(3.75f, 55.f));
+ EXPECT_EQ(AxisTransform2d(1.5625f, Vector2dF(3.75f, 55.f)),
+ PreScaleAxisTransform2d(t, 1.25));
+ t.PreScale(1.25);
+ EXPECT_EQ(AxisTransform2d(1.5625f, Vector2dF(3.75f, 55.f)), t);
+ }
+
+ {
+ AxisTransform2d t(1.25f, Vector2dF(3.75f, 55.f));
+ EXPECT_EQ(AxisTransform2d(1.5625f, Vector2dF(4.6875f, 68.75f)),
+ PostScaleAxisTransform2d(t, 1.25));
+ t.PostScale(1.25);
+ EXPECT_EQ(AxisTransform2d(1.5625f, Vector2dF(4.6875f, 68.75f)), t);
+ }
+}
+
+TEST(AxisTransform2dTest, Translating) {
+ Vector2dF tr(3.f, -5.f);
+ {
+ AxisTransform2d t(1.25f, Vector2dF(3.75f, 55.f));
+ EXPECT_EQ(AxisTransform2d(1.25f, Vector2dF(7.5f, 48.75f)),
+ PreTranslateAxisTransform2d(t, tr));
+ t.PreTranslate(tr);
+ EXPECT_EQ(AxisTransform2d(1.25f, Vector2dF(7.5f, 48.75f)), t);
+ }
+
+ {
+ AxisTransform2d t(1.25f, Vector2dF(3.75f, 55.f));
+ EXPECT_EQ(AxisTransform2d(1.25f, Vector2dF(6.75f, 50.f)),
+ PostTranslateAxisTransform2d(t, tr));
+ t.PostTranslate(tr);
+ EXPECT_EQ(AxisTransform2d(1.25f, Vector2dF(6.75f, 50.f)), t);
+ }
+}
+
+TEST(AxisTransform2dTest, Concat) {
+ AxisTransform2d pre(1.25f, Vector2dF(3.75f, 55.f));
+ AxisTransform2d post(0.5f, Vector2dF(10.f, 5.f));
+ AxisTransform2d expectation(0.625f, Vector2dF(11.875f, 32.5f));
+ EXPECT_EQ(expectation, ConcatAxisTransform2d(post, pre));
+
+ AxisTransform2d post_concat = pre;
+ post_concat.PostConcat(post);
+ EXPECT_EQ(expectation, post_concat);
+
+ AxisTransform2d pre_concat = post;
+ pre_concat.PreConcat(pre);
+ EXPECT_EQ(expectation, pre_concat);
+}
+
+TEST(AxisTransform2dTest, Inverse) {
+ AxisTransform2d t(1.25f, Vector2dF(3.75f, 55.f));
+ AxisTransform2d inv_inplace = t;
+ inv_inplace.Invert();
+ AxisTransform2d inv_out_of_place = InvertAxisTransform2d(t);
+
+ EXPECT_AXIS_TRANSFORM2D_EQ(inv_inplace, inv_out_of_place);
+ EXPECT_AXIS_TRANSFORM2D_EQ(AxisTransform2d(),
+ ConcatAxisTransform2d(t, inv_inplace));
+ EXPECT_AXIS_TRANSFORM2D_EQ(AxisTransform2d(),
+ ConcatAxisTransform2d(inv_inplace, t));
+}
+
+} // namespace
+} // namespace gfx
diff --git a/ui/gfx/test/gfx_util.cc b/ui/gfx/test/gfx_util.cc
index d8bf5f2a..e70b960 100644
--- a/ui/gfx/test/gfx_util.cc
+++ b/ui/gfx/test/gfx_util.cc
@@ -8,6 +8,7 @@
#include <sstream>
#include <string>
+#include "ui/gfx/geometry/axis_transform2d.h"
#include "ui/gfx/geometry/box_f.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point3_f.h"
@@ -45,6 +46,21 @@
} // namespace
+::testing::AssertionResult AssertAxisTransform2dFloatEqual(
+ const char* lhs_expr,
+ const char* rhs_expr,
+ const AxisTransform2d& lhs,
+ const AxisTransform2d& rhs) {
+ if (FloatAlmostEqual(lhs.scale(), rhs.scale()) &&
+ FloatAlmostEqual(lhs.translation().x(), rhs.translation().x()) &&
+ FloatAlmostEqual(lhs.translation().y(), rhs.translation().y())) {
+ return ::testing::AssertionSuccess();
+ }
+ return ::testing::AssertionFailure()
+ << "Value of: " << rhs_expr << "\n Actual: " << rhs.ToString()
+ << "\nExpected: " << lhs_expr << "\nWhich is: " << lhs.ToString();
+}
+
::testing::AssertionResult AssertBoxFloatEqual(const char* lhs_expr,
const char* rhs_expr,
const BoxF& lhs,
@@ -63,6 +79,19 @@
<< "\nWhich is: " << lhs.ToString();
}
+::testing::AssertionResult AssertPointFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const PointF& lhs,
+ const PointF& rhs) {
+ if (FloatAlmostEqual(lhs.x(), rhs.x()) &&
+ FloatAlmostEqual(lhs.y(), rhs.y())) {
+ return ::testing::AssertionSuccess();
+ }
+ return ::testing::AssertionFailure()
+ << "Value of: " << rhs_expr << "\n Actual: " << rhs.ToString()
+ << "\nExpected: " << lhs_expr << "\nWhich is: " << lhs.ToString();
+}
+
::testing::AssertionResult AssertRectFloatEqual(const char* lhs_expr,
const char* rhs_expr,
const RectF& lhs,
@@ -91,6 +120,10 @@
<< "\nWhich is: " << ColorAsString(lhs);
}
+void PrintTo(const AxisTransform2d& transform, ::std::ostream* os) {
+ *os << transform.ToString();
+}
+
void PrintTo(const BoxF& box, ::std::ostream* os) {
*os << box.ToString();
}
diff --git a/ui/gfx/test/gfx_util.h b/ui/gfx/test/gfx_util.h
index 1401d5c..e7ed59d 100644
--- a/ui/gfx/test/gfx_util.h
+++ b/ui/gfx/test/gfx_util.h
@@ -10,12 +10,23 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/box_f.h"
-#include "ui/gfx/geometry/rect_f.h"
namespace gfx {
-// Checks that the box coordinates are each almost equal floats.
+class AxisTransform2d;
+class BoxF;
+class PointF;
+class RectF;
+
+#define EXPECT_AXIS_TRANSFORM2D_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertAxisTransform2dFloatEqual, a, b)
+
+::testing::AssertionResult AssertAxisTransform2dFloatEqual(
+ const char* lhs_expr,
+ const char* rhs_expr,
+ const AxisTransform2d& lhs,
+ const AxisTransform2d& rhs);
+
#define EXPECT_BOXF_EQ(a, b) \
EXPECT_PRED_FORMAT2(::gfx::AssertBoxFloatEqual, a, b)
@@ -24,6 +35,14 @@
const BoxF& lhs,
const BoxF& rhs);
+#define EXPECT_POINTF_EQ(a, b) \
+ EXPECT_PRED_FORMAT2(::gfx::AssertPointFloatEqual, a, b)
+
+::testing::AssertionResult AssertPointFloatEqual(const char* lhs_expr,
+ const char* rhs_expr,
+ const PointF& lhs,
+ const PointF& rhs);
+
#define EXPECT_RECTF_EQ(a, b) \
EXPECT_PRED_FORMAT2(::gfx::AssertRectFloatEqual, a, b)