Commit 0aa176fe authored by Michael Tang's avatar Michael Tang Committed by Commit Bot

[Paint Preview] Remove PaintPreviewTracker scroll offset

- Formalize coordinate space of subframe placeholders to be in their parent's space.

Bug: 1009552
Change-Id: I75c44a648acc18696e019c669d850bc842823af4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2363875Reviewed-by: default avatarCalder Kitagawa <ckitagawa@chromium.org>
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801354}
parent fc4b6db7
...@@ -44,8 +44,7 @@ PaintPreviewTracker::PaintPreviewTracker( ...@@ -44,8 +44,7 @@ PaintPreviewTracker::PaintPreviewTracker(
bool is_main_frame) bool is_main_frame)
: guid_(guid), : guid_(guid),
embedding_token_(embedding_token), embedding_token_(embedding_token),
is_main_frame_(is_main_frame), is_main_frame_(is_main_frame) {}
scroll_(SkISize::Make(0, 0)) {}
PaintPreviewTracker::~PaintPreviewTracker() { PaintPreviewTracker::~PaintPreviewTracker() {
DCHECK(states_.empty()); DCHECK(states_.empty());
...@@ -96,8 +95,7 @@ uint32_t PaintPreviewTracker::CreateContentForRemoteFrame( ...@@ -96,8 +95,7 @@ uint32_t PaintPreviewTracker::CreateContentForRemoteFrame(
const gfx::Rect& rect, const gfx::Rect& rect,
const base::UnguessableToken& embedding_token) { const base::UnguessableToken& embedding_token) {
sk_sp<SkPicture> pic = SkPicture::MakePlaceholder( sk_sp<SkPicture> pic = SkPicture::MakePlaceholder(
SkRect::MakeXYWH(rect.x() + scroll_.width(), rect.y() + scroll_.height(), SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()));
rect.width(), rect.height()));
const uint32_t content_id = pic->uniqueID(); const uint32_t content_id = pic->uniqueID();
DCHECK(!base::Contains(picture_context_.content_id_to_embedding_token, DCHECK(!base::Contains(picture_context_.content_id_to_embedding_token,
content_id)); content_id));
...@@ -106,10 +104,6 @@ uint32_t PaintPreviewTracker::CreateContentForRemoteFrame( ...@@ -106,10 +104,6 @@ uint32_t PaintPreviewTracker::CreateContentForRemoteFrame(
return content_id; return content_id;
} }
void PaintPreviewTracker::SetScrollForFrame(const SkISize& scroll) {
scroll_ = scroll;
}
void PaintPreviewTracker::AddGlyphs(const SkTextBlob* blob) { void PaintPreviewTracker::AddGlyphs(const SkTextBlob* blob) {
if (!blob) if (!blob)
return; return;
...@@ -170,8 +164,8 @@ void PaintPreviewTracker::CustomDataToSkPictureCallback(SkCanvas* canvas, ...@@ -170,8 +164,8 @@ void PaintPreviewTracker::CustomDataToSkPictureCallback(SkCanvas* canvas,
DCHECK(it != subframe_pics_.end()); DCHECK(it != subframe_pics_.end());
SkRect rect = it->second->cullRect(); SkRect rect = it->second->cullRect();
SkMatrix matrix = SkMatrix::Translate(rect.x(), rect.y()); SkMatrix subframe_offset = SkMatrix::Translate(rect.x(), rect.y());
canvas->drawPicture(it->second, &matrix, nullptr); canvas->drawPicture(it->second, &subframe_offset, nullptr);
} }
void PaintPreviewTracker::MoveLinks(std::vector<mojom::LinkDataPtr>* out) { void PaintPreviewTracker::MoveLinks(std::vector<mojom::LinkDataPtr>* out) {
......
...@@ -62,9 +62,6 @@ class PaintPreviewTracker { ...@@ -62,9 +62,6 @@ class PaintPreviewTracker {
const gfx::Rect& rect, const gfx::Rect& rect,
const base::UnguessableToken& embedding_token); const base::UnguessableToken& embedding_token);
// Sets the scroll position for the top layer frame.
void SetScrollForFrame(const SkISize& scroll);
// Adds the glyphs in |blob| to the glyph usage tracker for the |blob|'s // Adds the glyphs in |blob| to the glyph usage tracker for the |blob|'s
// associated typface. // associated typface.
void AddGlyphs(const SkTextBlob* blob); void AddGlyphs(const SkTextBlob* blob);
...@@ -85,7 +82,8 @@ class PaintPreviewTracker { ...@@ -85,7 +82,8 @@ class PaintPreviewTracker {
// be considered immutable. // be considered immutable.
// Inserts the OOP subframe placeholder associated with |content_id| into // Inserts the OOP subframe placeholder associated with |content_id| into
// |canvas|. // |canvas|. The cull rect of the placeholder will encode the position and
// size of the the subframe in its parent's coordinate system.
void CustomDataToSkPictureCallback(SkCanvas* canvas, uint32_t content_id); void CustomDataToSkPictureCallback(SkCanvas* canvas, uint32_t content_id);
// Expose internal maps for use in MakeSerialProcs(). // Expose internal maps for use in MakeSerialProcs().
...@@ -111,7 +109,6 @@ class PaintPreviewTracker { ...@@ -111,7 +109,6 @@ class PaintPreviewTracker {
const base::Optional<base::UnguessableToken> embedding_token_; const base::Optional<base::UnguessableToken> embedding_token_;
const bool is_main_frame_; const bool is_main_frame_;
SkISize scroll_;
SkMatrix matrix_; SkMatrix matrix_;
std::vector<SkMatrix> states_; std::vector<SkMatrix> states_;
......
...@@ -4,12 +4,14 @@ ...@@ -4,12 +4,14 @@
#include "components/paint_preview/common/paint_preview_tracker.h" #include "components/paint_preview/common/paint_preview_tracker.h"
#include "base/containers/flat_map.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "components/paint_preview/common/serial_utils.h" #include "components/paint_preview/common/serial_utils.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTextBlob.h" #include "third_party/skia/include/core/SkTextBlob.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
...@@ -23,6 +25,36 @@ struct TestContext { ...@@ -23,6 +25,36 @@ struct TestContext {
bool was_called; bool was_called;
}; };
// A test canvas for checking that the pictures drawn to it have the cull rect
// we expect them to.
class ExpectSubframeCanvas : public SkCanvas {
public:
void onDrawPicture(const SkPicture* picture,
const SkMatrix*,
const SkPaint*) override {
drawn_pictures_.insert({picture->uniqueID(), picture->cullRect()});
}
void ExpectHasPicture(uint32_t expected_picture_id,
const gfx::Rect& expected_bounds) {
auto it = drawn_pictures_.find(expected_picture_id);
if (it == drawn_pictures_.end()) {
ADD_FAILURE() << "Picture ID was not recorded.";
return;
}
SkIRect rect = it->second.round();
EXPECT_EQ(rect.x(), expected_bounds.x());
EXPECT_EQ(rect.y(), expected_bounds.y());
EXPECT_EQ(rect.width(), expected_bounds.width());
EXPECT_EQ(rect.height(), expected_bounds.height());
}
private:
// Map of picture id to expected bounds of pictures drawn into this canvas.
base::flat_map<uint32_t, SkRect> drawn_pictures_;
};
} // namespace } // namespace
TEST(PaintPreviewTrackerTest, TestGetters) { TEST(PaintPreviewTrackerTest, TestGetters) {
...@@ -52,42 +84,10 @@ TEST(PaintPreviewTrackerTest, TestRemoteFramePlaceholderPicture) { ...@@ -52,42 +84,10 @@ TEST(PaintPreviewTrackerTest, TestRemoteFramePlaceholderPicture) {
EXPECT_EQ(context->content_id_to_embedding_token[content_id], EXPECT_EQ(context->content_id_to_embedding_token[content_id],
kEmbeddingTokenChild); kEmbeddingTokenChild);
SkPictureRecorder recorder; ExpectSubframeCanvas canvas;
SkCanvas* canvas = recorder.beginRecording(100, 100); tracker.CustomDataToSkPictureCallback(&canvas, content_id);
tracker.CustomDataToSkPictureCallback(canvas, content_id);
sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture();
// TODO(crbug/1009552): find a good way to check that a filler picture was
// actually inserted into |pic|. This is difficult without using the
// underlying private picture record.
}
TEST(PaintPreviewTrackerTest, TestRemoteFramePlaceholderPictureWithScroll) {
const base::UnguessableToken kDocToken = base::UnguessableToken::Create();
const base::UnguessableToken kEmbeddingToken =
base::UnguessableToken::Create();
PaintPreviewTracker tracker(kDocToken, kEmbeddingToken, true);
tracker.SetScrollForFrame(SkISize::Make(10, 20));
const base::UnguessableToken kEmbeddingTokenChild =
base::UnguessableToken::Create();
gfx::Rect rect(50, 40, 30, 20);
uint32_t content_id =
tracker.CreateContentForRemoteFrame(rect, kEmbeddingTokenChild);
PictureSerializationContext* context =
tracker.GetPictureSerializationContext();
EXPECT_TRUE(context->content_id_to_embedding_token.count(content_id));
EXPECT_EQ(context->content_id_to_embedding_token[content_id],
kEmbeddingTokenChild);
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(100, 100);
tracker.CustomDataToSkPictureCallback(canvas, content_id);
sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture();
// TODO(crbug/1009552): find a good way to check that a filler picture was canvas.ExpectHasPicture(content_id, rect);
// actually inserted into |pic|. This is difficult without using the
// underlying private picture record.
} }
TEST(PaintPreviewTrackerTest, TestGlyphRunList) { TEST(PaintPreviewTrackerTest, TestGlyphRunList) {
......
...@@ -18,10 +18,12 @@ namespace { ...@@ -18,10 +18,12 @@ namespace {
#pragma pack(push, 1) #pragma pack(push, 1)
struct SerializedRectData { struct SerializedRectData {
uint32_t content_id; uint32_t content_id;
int64_t x;
int64_t y; // The size of the subframe in the local coordinates when it was drawn.
int64_t width; int64_t subframe_width;
int64_t height; int64_t subframe_height;
// The rect of the subframe in its parent frame's root coordinate system.
int64_t transformed_x; int64_t transformed_x;
int64_t transformed_y; int64_t transformed_y;
int64_t transformed_width; int64_t transformed_width;
...@@ -39,10 +41,10 @@ sk_sp<SkData> SerializePictureAsRectData(SkPicture* picture, void* ctx) { ...@@ -39,10 +41,10 @@ sk_sp<SkData> SerializePictureAsRectData(SkPicture* picture, void* ctx) {
if (it == context->content_id_to_transformed_clip.end()) if (it == context->content_id_to_transformed_clip.end())
return nullptr; return nullptr;
// This data originates from |PaintPreviewTracker|.
const SkRect& transformed_cull_rect = it->second; const SkRect& transformed_cull_rect = it->second;
SerializedRectData rect_data = { SerializedRectData rect_data = {
picture->uniqueID(), picture->cullRect().x(), picture->uniqueID(), picture->cullRect().width(),
picture->cullRect().y(), picture->cullRect().width(),
picture->cullRect().height(), transformed_cull_rect.x(), picture->cullRect().height(), transformed_cull_rect.x(),
transformed_cull_rect.y(), transformed_cull_rect.width(), transformed_cull_rect.y(), transformed_cull_rect.width(),
transformed_cull_rect.height()}; transformed_cull_rect.height()};
...@@ -71,7 +73,7 @@ sk_sp<SkData> SerializeTypeface(SkTypeface* typeface, void* ctx) { ...@@ -71,7 +73,7 @@ sk_sp<SkData> SerializeTypeface(SkTypeface* typeface, void* ctx) {
return subset_data; return subset_data;
} }
// Deserializies a clip rect for a subframe within the main SkPicture. These // Deserializes a clip rect for a subframe within the main SkPicture. These
// represent subframes and require special decoding as they are custom data // represent subframes and require special decoding as they are custom data
// rather than a valid SkPicture. // rather than a valid SkPicture.
// Precondition: the version of the SkPicture should be checked prior to // Precondition: the version of the SkPicture should be checked prior to
...@@ -106,21 +108,19 @@ sk_sp<SkPicture> GetPictureFromDeserialContext(const void* data, ...@@ -106,21 +108,19 @@ sk_sp<SkPicture> GetPictureFromDeserialContext(const void* data,
memcpy(&rect_data, data, sizeof(rect_data)); memcpy(&rect_data, data, sizeof(rect_data));
auto* context = reinterpret_cast<LoadedFramesDeserialContext*>(ctx); auto* context = reinterpret_cast<LoadedFramesDeserialContext*>(ctx);
auto it = context->subframes.find(rect_data.content_id); auto it = context->find(rect_data.content_id);
if (it == context->subframes.end()) if (it == context->end())
return MakeEmptyPicture(); return MakeEmptyPicture();
// Scroll and clip the subframe manually since the picture in |ctx| does not // Scroll and clip the subframe manually since the picture in |ctx| does not
// encode this information. // encode this information.
SkRect subframe_bounds = SkRect::MakeWH(rect_data.width, rect_data.height); SkRect subframe_bounds =
subframe_bounds.offset(-context->scroll_offsets.width(), SkRect::MakeWH(rect_data.subframe_width, rect_data.subframe_height);
-context->scroll_offsets.height());
SkPictureRecorder recorder; SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(subframe_bounds); SkCanvas* canvas = recorder.beginRecording(subframe_bounds);
canvas->clipRect(subframe_bounds); canvas->clipRect(subframe_bounds);
SkMatrix apply_scroll_offsets = SkMatrix::Translate( SkMatrix apply_scroll_offsets = SkMatrix::Translate(
-context->scroll_offsets.width() - it->second.scroll_offsets.width(), -it->second.scroll_offsets.width(), -it->second.scroll_offsets.height());
-context->scroll_offsets.height() - it->second.scroll_offsets.height());
canvas->drawPicture(it->second.picture, &apply_scroll_offsets, nullptr); canvas->drawPicture(it->second.picture, &apply_scroll_offsets, nullptr);
return recorder.finishRecordingAsPicture(); return recorder.finishRecordingAsPicture();
} }
...@@ -147,9 +147,6 @@ FrameAndScrollOffsets::FrameAndScrollOffsets(const FrameAndScrollOffsets&) = ...@@ -147,9 +147,6 @@ FrameAndScrollOffsets::FrameAndScrollOffsets(const FrameAndScrollOffsets&) =
FrameAndScrollOffsets& FrameAndScrollOffsets::operator=( FrameAndScrollOffsets& FrameAndScrollOffsets::operator=(
const FrameAndScrollOffsets&) = default; const FrameAndScrollOffsets&) = default;
LoadedFramesDeserialContext::LoadedFramesDeserialContext() = default;
LoadedFramesDeserialContext::~LoadedFramesDeserialContext() = default;
sk_sp<SkPicture> MakeEmptyPicture() { sk_sp<SkPicture> MakeEmptyPicture() {
// Effectively a no-op. // Effectively a no-op.
SkPictureRecorder rec; SkPictureRecorder rec;
......
...@@ -69,20 +69,11 @@ struct FrameAndScrollOffsets { ...@@ -69,20 +69,11 @@ struct FrameAndScrollOffsets {
gfx::Size scroll_offsets; gfx::Size scroll_offsets;
}; };
// Deserialization context for |MakeDeserialProcs| that contains the information // Maps a content ID to a frame's picture. A frame's subframes should be
// needed to embed a subframe within its parent frame. // loaded into this context before |MakeDeserialProcs| is called to ensure
struct LoadedFramesDeserialContext { // that the resulting |SkPicture| contains all subframes.
LoadedFramesDeserialContext(); using LoadedFramesDeserialContext =
~LoadedFramesDeserialContext(); base::flat_map<uint32_t, FrameAndScrollOffsets>;
// The scroll offsets for the current frame.
gfx::Size scroll_offsets;
// Maps a content ID to a frame's picture. A frame's subframes should be
// loaded into this context before |MakeDeserialProcs| is called to ensure
// that the resulting |SkPicture| contains all subframes.
base::flat_map<uint32_t, FrameAndScrollOffsets> subframes;
};
// Creates a no-op SkPicture. // Creates a no-op SkPicture.
sk_sp<SkPicture> MakeEmptyPicture(); sk_sp<SkPicture> MakeEmptyPicture();
......
...@@ -187,7 +187,6 @@ void PaintPreviewRecorderImpl::CapturePaintPreviewInternal( ...@@ -187,7 +187,6 @@ void PaintPreviewRecorderImpl::CapturePaintPreviewInternal(
auto tracker = std::make_unique<PaintPreviewTracker>( auto tracker = std::make_unique<PaintPreviewTracker>(
params->guid, frame->GetEmbeddingToken(), is_main_frame_); params->guid, frame->GetEmbeddingToken(), is_main_frame_);
auto size = frame->GetScrollOffset(); auto size = frame->GetScrollOffset();
tracker->SetScrollForFrame(SkISize::Make(size.width, size.height));
response->scroll_offsets = gfx::Size(size.width, size.height); response->scroll_offsets = gfx::Size(size.width, size.height);
cc::PaintRecorder recorder; cc::PaintRecorder recorder;
......
...@@ -337,9 +337,6 @@ sk_sp<SkPicture> PaintPreviewCompositorImpl::DeserializeFrameRecursive( ...@@ -337,9 +337,6 @@ sk_sp<SkPicture> PaintPreviewCompositorImpl::DeserializeFrameRecursive(
// before the current frame is loaded to ensure the order of loading is // before the current frame is loaded to ensure the order of loading is
// topologically sorted. // topologically sorted.
LoadedFramesDeserialContext deserial_context; LoadedFramesDeserialContext deserial_context;
deserial_context.scroll_offsets = gfx::Size(
frame_proto.has_scroll_offset_x() ? frame_proto.scroll_offset_x() : 0,
frame_proto.has_scroll_offset_y() ? frame_proto.scroll_offset_y() : 0);
*subframe_failed = false; *subframe_failed = false;
for (const auto& id_pair : frame_proto.content_id_to_embedding_tokens()) { for (const auto& id_pair : frame_proto.content_id_to_embedding_tokens()) {
...@@ -396,7 +393,7 @@ sk_sp<SkPicture> PaintPreviewCompositorImpl::DeserializeFrameRecursive( ...@@ -396,7 +393,7 @@ sk_sp<SkPicture> PaintPreviewCompositorImpl::DeserializeFrameRecursive(
subframe_proto_it->has_scroll_offset_y() subframe_proto_it->has_scroll_offset_y()
? subframe_proto_it->scroll_offset_y() ? subframe_proto_it->scroll_offset_y()
: 0); : 0);
deserial_context.subframes.insert({id_pair.content_id(), frame}); deserial_context.insert({id_pair.content_id(), frame});
} }
auto recording_it = recording_map->find(frame_guid); auto recording_it = recording_map->find(frame_guid);
......
...@@ -208,10 +208,6 @@ void PopulateFrameProto( ...@@ -208,10 +208,6 @@ void PopulateFrameProto(
// observing it. // observing it.
PaintPreviewTracker tracker(base::UnguessableToken::Create(), guid, PaintPreviewTracker tracker(base::UnguessableToken::Create(), guid,
set_is_main_frame); set_is_main_frame);
if (set_is_main_frame) {
tracker.SetScrollForFrame(
SkISize::Make(scroll_offsets.width(), scroll_offsets.height()));
}
mojom::FrameDataPtr expected_frame_data = mojom::FrameData::New(); mojom::FrameDataPtr expected_frame_data = mojom::FrameData::New();
expected_frame_data->scroll_extents = scroll_extents; expected_frame_data->scroll_extents = scroll_extents;
expected_frame_data->scroll_offsets = scroll_offsets; expected_frame_data->scroll_offsets = scroll_offsets;
......
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