Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: content/shell/test_runner/pixel_dump.cc

Issue 2963593002: Split DumpPixelsAsync in pixel_dump.h into more granular functions. (Closed)
Patch Set: Addressed CR feedback from alexmos@. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/shell/test_runner/pixel_dump.h ('k') | content/shell/test_runner/test_runner.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/shell/test_runner/pixel_dump.h" 5 #include "content/shell/test_runner/pixel_dump.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
16 #include "cc/paint/paint_flags.h" 16 #include "cc/paint/paint_flags.h"
17 #include "cc/paint/skia_paint_canvas.h" 17 #include "cc/paint/skia_paint_canvas.h"
18 #include "content/shell/test_runner/layout_test_runtime_flags.h" 18 #include "content/shell/test_runner/layout_test_runtime_flags.h"
19 // FIXME: Including platform_canvas.h here is a layering violation. 19 // FIXME: Including platform_canvas.h here is a layering violation.
20 #include "skia/ext/platform_canvas.h" 20 #include "skia/ext/platform_canvas.h"
21 #include "third_party/WebKit/public/platform/Platform.h" 21 #include "third_party/WebKit/public/platform/Platform.h"
22 #include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallbac k.h" 22 #include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallbac k.h"
23 #include "third_party/WebKit/public/platform/WebImage.h" 23 #include "third_party/WebKit/public/platform/WebImage.h"
24 #include "third_party/WebKit/public/platform/WebMockClipboard.h" 24 #include "third_party/WebKit/public/platform/WebMockClipboard.h"
25 #include "third_party/WebKit/public/platform/WebPoint.h" 25 #include "third_party/WebKit/public/platform/WebPoint.h"
26 #include "third_party/WebKit/public/web/WebFrame.h" 26 #include "third_party/WebKit/public/web/WebFrame.h"
27 #include "third_party/WebKit/public/web/WebFrameWidget.h"
27 #include "third_party/WebKit/public/web/WebLocalFrame.h" 28 #include "third_party/WebKit/public/web/WebLocalFrame.h"
28 #include "third_party/WebKit/public/web/WebPagePopup.h" 29 #include "third_party/WebKit/public/web/WebPagePopup.h"
29 #include "third_party/WebKit/public/web/WebPrintParams.h" 30 #include "third_party/WebKit/public/web/WebPrintParams.h"
30 #include "third_party/WebKit/public/web/WebView.h"
31 #include "ui/gfx/geometry/point.h" 31 #include "ui/gfx/geometry/point.h"
32 32
33 namespace test_runner { 33 namespace test_runner {
34 34
35 namespace { 35 namespace {
36 36
37 struct PixelsDumpRequest {
38 PixelsDumpRequest(blink::WebView* web_view,
39 const LayoutTestRuntimeFlags& layout_test_runtime_flags,
40 const base::Callback<void(const SkBitmap&)>& callback)
41 : web_view(web_view),
42 layout_test_runtime_flags(layout_test_runtime_flags),
43 callback(callback) {}
44
45 blink::WebView* web_view;
46 const LayoutTestRuntimeFlags& layout_test_runtime_flags;
47 base::Callback<void(const SkBitmap&)> callback;
48 };
49
50 class CaptureCallback : public blink::WebCompositeAndReadbackAsyncCallback { 37 class CaptureCallback : public blink::WebCompositeAndReadbackAsyncCallback {
51 public: 38 public:
52 explicit CaptureCallback( 39 explicit CaptureCallback(base::OnceCallback<void(const SkBitmap&)> callback);
53 const base::Callback<void(const SkBitmap&)>& callback);
54 virtual ~CaptureCallback(); 40 virtual ~CaptureCallback();
55 41
56 void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; } 42 void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; }
57 void set_popup_position(const gfx::Point& position) { 43 void set_popup_position(const gfx::Point& position) {
58 popup_position_ = position; 44 popup_position_ = position;
59 } 45 }
60 46
61 // WebCompositeAndReadbackAsyncCallback implementation. 47 // WebCompositeAndReadbackAsyncCallback implementation.
62 void DidCompositeAndReadback(const SkBitmap& bitmap) override; 48 void DidCompositeAndReadback(const SkBitmap& bitmap) override;
63 49
64 private: 50 private:
65 base::Callback<void(const SkBitmap&)> callback_; 51 base::OnceCallback<void(const SkBitmap&)> callback_;
66 SkBitmap main_bitmap_; 52 SkBitmap main_bitmap_;
67 bool wait_for_popup_; 53 bool wait_for_popup_;
68 gfx::Point popup_position_; 54 gfx::Point popup_position_;
69 }; 55 };
70 56
71 void DrawSelectionRect(const PixelsDumpRequest& dump_request, 57 void DrawSelectionRect(
72 cc::PaintCanvas* canvas) { 58 const blink::WebRect& wr,
73 // See if we need to draw the selection bounds rect. Selection bounds 59 base::OnceCallback<void(const SkBitmap&)> original_callback,
74 // rect is the rect enclosing the (possibly transformed) selection. 60 const SkBitmap& bitmap) {
75 // The rect should be drawn after everything is laid out and painted.
76 if (!dump_request.layout_test_runtime_flags.dump_selection_rect())
77 return;
78
79 // TODO(lukasza): https://crbug.com/667551: Support OOPIFs in pixel dumps.
80 CHECK(dump_request.web_view->MainFrame()->IsWebLocalFrame())
81 << "This function cannot be called if the main frame is not a "
82 "local frame.";
83
84 // If there is a selection rect - draw a red 1px border enclosing rect
85 blink::WebRect wr = dump_request.web_view->MainFrame()
86 ->ToWebLocalFrame()
87 ->GetSelectionBoundsRectForTesting();
88 if (wr.IsEmpty())
89 return;
90 // Render a red rectangle bounding selection rect 61 // Render a red rectangle bounding selection rect
62 cc::SkiaPaintCanvas canvas(bitmap);
91 cc::PaintFlags flags; 63 cc::PaintFlags flags;
92 flags.setColor(0xFFFF0000); // Fully opaque red 64 flags.setColor(0xFFFF0000); // Fully opaque red
93 flags.setStyle(cc::PaintFlags::kStroke_Style); 65 flags.setStyle(cc::PaintFlags::kStroke_Style);
94 flags.setAntiAlias(true); 66 flags.setAntiAlias(true);
95 flags.setStrokeWidth(1.0f); 67 flags.setStrokeWidth(1.0f);
96 SkIRect rect; // Bounding rect 68 SkIRect rect; // Bounding rect
97 rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height); 69 rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
98 canvas->drawIRect(rect, flags); 70 canvas.drawIRect(rect, flags);
71
72 std::move(original_callback).Run(bitmap);
99 } 73 }
100 74
101 void CapturePixelsForPrinting(std::unique_ptr<PixelsDumpRequest> dump_request) { 75 void CapturePixelsForPrinting(
102 dump_request->web_view->UpdateAllLifecyclePhases(); 76 blink::WebLocalFrame* web_frame,
77 base::OnceCallback<void(const SkBitmap&)> callback) {
78 web_frame->FrameWidget()->UpdateAllLifecyclePhases();
103 79
104 blink::WebSize page_size_in_pixels = dump_request->web_view->Size(); 80 blink::WebSize page_size_in_pixels = web_frame->FrameWidget()->Size();
105
106 // TODO(lukasza): https://crbug.com/667551: Support OOPIFs in pixel dumps.
107 CHECK(dump_request->web_view->MainFrame()->IsWebLocalFrame())
108 << "This function cannot be called if the main frame is not a "
109 "local frame.";
110 blink::WebLocalFrame* web_frame =
111 dump_request->web_view->MainFrame()->ToWebLocalFrame();
112 81
113 int page_count = web_frame->PrintBegin(page_size_in_pixels); 82 int page_count = web_frame->PrintBegin(page_size_in_pixels);
114 int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1; 83 int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1;
115 84
116 bool is_opaque = false; 85 bool is_opaque = false;
117 86
118 SkBitmap bitmap; 87 SkBitmap bitmap;
119 if (!bitmap.tryAllocN32Pixels(page_size_in_pixels.width, totalHeight, 88 if (!bitmap.tryAllocN32Pixels(page_size_in_pixels.width, totalHeight,
120 is_opaque)) { 89 is_opaque)) {
121 LOG(ERROR) << "Failed to create bitmap width=" << page_size_in_pixels.width 90 LOG(ERROR) << "Failed to create bitmap width=" << page_size_in_pixels.width
122 << " height=" << totalHeight; 91 << " height=" << totalHeight;
123 dump_request->callback.Run(SkBitmap()); 92 std::move(callback).Run(SkBitmap());
124 return; 93 return;
125 } 94 }
126 95
127 cc::SkiaPaintCanvas canvas(bitmap); 96 cc::SkiaPaintCanvas canvas(bitmap);
128 web_frame->PrintPagesForTesting(&canvas, page_size_in_pixels); 97 web_frame->PrintPagesForTesting(&canvas, page_size_in_pixels);
129 web_frame->PrintEnd(); 98 web_frame->PrintEnd();
130 99
131 DrawSelectionRect(*dump_request, &canvas); 100 std::move(callback).Run(bitmap);
132 dump_request->callback.Run(bitmap);
133 } 101 }
134 102
135 CaptureCallback::CaptureCallback( 103 CaptureCallback::CaptureCallback(
136 const base::Callback<void(const SkBitmap&)>& callback) 104 base::OnceCallback<void(const SkBitmap&)> callback)
137 : callback_(callback), wait_for_popup_(false) {} 105 : callback_(std::move(callback)), wait_for_popup_(false) {}
138 106
139 CaptureCallback::~CaptureCallback() {} 107 CaptureCallback::~CaptureCallback() {}
140 108
141 void CaptureCallback::DidCompositeAndReadback(const SkBitmap& bitmap) { 109 void CaptureCallback::DidCompositeAndReadback(const SkBitmap& bitmap) {
142 TRACE_EVENT2("shell", "CaptureCallback::didCompositeAndReadback", "x", 110 TRACE_EVENT2("shell", "CaptureCallback::didCompositeAndReadback", "x",
143 bitmap.info().width(), "y", bitmap.info().height()); 111 bitmap.info().width(), "y", bitmap.info().height());
144 if (!wait_for_popup_) { 112 if (!wait_for_popup_) {
145 callback_.Run(bitmap); 113 std::move(callback_).Run(bitmap);
146 delete this; 114 delete this;
147 return; 115 return;
148 } 116 }
149 if (main_bitmap_.isNull()) { 117 if (main_bitmap_.isNull()) {
150 if (main_bitmap_.tryAllocPixels(bitmap.info())) { 118 if (main_bitmap_.tryAllocPixels(bitmap.info())) {
151 bitmap.readPixels(main_bitmap_.info(), main_bitmap_.getPixels(), 119 bitmap.readPixels(main_bitmap_.info(), main_bitmap_.getPixels(),
152 main_bitmap_.rowBytes(), 0, 0); 120 main_bitmap_.rowBytes(), 0, 0);
153 } 121 }
154 return; 122 return;
155 } 123 }
156 SkCanvas canvas(main_bitmap_); 124 SkCanvas canvas(main_bitmap_);
157 canvas.drawBitmap(bitmap, popup_position_.x(), popup_position_.y()); 125 canvas.drawBitmap(bitmap, popup_position_.x(), popup_position_.y());
158 callback_.Run(main_bitmap_); 126 std::move(callback_).Run(main_bitmap_);
159 delete this; 127 delete this;
160 } 128 }
161 129
162 void DidCapturePixelsAsync(std::unique_ptr<PixelsDumpRequest> dump_request,
163 const SkBitmap& bitmap) {
164 cc::SkiaPaintCanvas canvas(bitmap);
165 DrawSelectionRect(*dump_request, &canvas);
166 if (!dump_request->callback.is_null())
167 dump_request->callback.Run(bitmap);
168 }
169
170 } // namespace 130 } // namespace
171 131
172 void DumpPixelsAsync(blink::WebView* web_view, 132 void DumpPixelsAsync(blink::WebLocalFrame* web_frame,
173 const LayoutTestRuntimeFlags& layout_test_runtime_flags,
174 float device_scale_factor_for_test, 133 float device_scale_factor_for_test,
175 const base::Callback<void(const SkBitmap&)>& callback) { 134 base::OnceCallback<void(const SkBitmap&)> callback) {
176 TRACE_EVENT0("shell", "WebViewTestProxyBase::CapturePixelsAsync"); 135 DCHECK(web_frame);
136 DCHECK_LT(0.0, device_scale_factor_for_test);
177 DCHECK(!callback.is_null()); 137 DCHECK(!callback.is_null());
178 DCHECK(!layout_test_runtime_flags.dump_drag_image());
179 138
180 std::unique_ptr<PixelsDumpRequest> pixels_request( 139 blink::WebWidget* web_widget = web_frame->FrameWidget();
181 new PixelsDumpRequest(web_view, layout_test_runtime_flags, callback)); 140 CaptureCallback* capture_callback = new CaptureCallback(std::move(callback));
182 141 web_widget->CompositeAndReadbackAsync(capture_callback);
183 if (layout_test_runtime_flags.is_printing()) { 142 if (blink::WebPagePopup* popup = web_widget->GetPagePopup()) {
184 base::ThreadTaskRunnerHandle::Get()->PostTask(
185 FROM_HERE, base::Bind(&CapturePixelsForPrinting,
186 base::Passed(std::move(pixels_request))));
187 return;
188 }
189
190 CaptureCallback* capture_callback = new CaptureCallback(base::Bind(
191 &DidCapturePixelsAsync, base::Passed(std::move(pixels_request))));
192 web_view->CompositeAndReadbackAsync(capture_callback);
193 if (blink::WebPagePopup* popup = web_view->GetPagePopup()) {
194 capture_callback->set_wait_for_popup(true); 143 capture_callback->set_wait_for_popup(true);
195 blink::WebPoint position = popup->PositionRelativeToOwner(); 144 blink::WebPoint position = popup->PositionRelativeToOwner();
196 position.x *= device_scale_factor_for_test; 145 position.x *= device_scale_factor_for_test;
197 position.y *= device_scale_factor_for_test; 146 position.y *= device_scale_factor_for_test;
198 capture_callback->set_popup_position(position); 147 capture_callback->set_popup_position(position);
199 popup->CompositeAndReadbackAsync(capture_callback); 148 popup->CompositeAndReadbackAsync(capture_callback);
200 } 149 }
201 } 150 }
202 151
152 void PrintFrameAsync(blink::WebLocalFrame* web_frame,
153 base::OnceCallback<void(const SkBitmap&)> callback) {
154 DCHECK(web_frame);
155 DCHECK(!callback.is_null());
156 base::ThreadTaskRunnerHandle::Get()->PostTask(
157 FROM_HERE,
158 base::Bind(&CapturePixelsForPrinting, base::Unretained(web_frame),
159 base::Passed(std::move(callback))));
160 }
161
162 base::OnceCallback<void(const SkBitmap&)>
163 CreateSelectionBoundsRectDrawingCallback(
164 blink::WebLocalFrame* web_frame,
165 base::OnceCallback<void(const SkBitmap&)> original_callback) {
166 DCHECK(web_frame);
167 DCHECK(!original_callback.is_null());
168
169 // If there is no selection rect, just return the original callback.
170 blink::WebRect wr = web_frame->GetSelectionBoundsRectForTesting();
171 if (wr.IsEmpty())
172 return original_callback;
173
174 return base::Bind(&DrawSelectionRect, wr,
175 base::Passed(std::move(original_callback)));
176 }
177
203 void CopyImageAtAndCapturePixels( 178 void CopyImageAtAndCapturePixels(
204 blink::WebView* web_view, 179 blink::WebLocalFrame* web_frame,
205 int x, 180 int x,
206 int y, 181 int y,
207 const base::Callback<void(const SkBitmap&)>& callback) { 182 base::OnceCallback<void(const SkBitmap&)> callback) {
208 DCHECK(!callback.is_null()); 183 DCHECK(!callback.is_null());
209 uint64_t sequence_number = 184 uint64_t sequence_number =
210 blink::Platform::Current()->Clipboard()->SequenceNumber( 185 blink::Platform::Current()->Clipboard()->SequenceNumber(
211 blink::WebClipboard::Buffer()); 186 blink::WebClipboard::Buffer());
212 // TODO(lukasza): Support image capture in OOPIFs for 187 web_frame->CopyImageAt(blink::WebPoint(x, y));
213 // https://crbug.com/477150.
214 web_view->MainFrame()->ToWebLocalFrame()->CopyImageAt(blink::WebPoint(x, y));
215 if (sequence_number == 188 if (sequence_number ==
216 blink::Platform::Current()->Clipboard()->SequenceNumber( 189 blink::Platform::Current()->Clipboard()->SequenceNumber(
217 blink::WebClipboard::Buffer())) { 190 blink::WebClipboard::Buffer())) {
218 SkBitmap emptyBitmap; 191 SkBitmap emptyBitmap;
219 callback.Run(emptyBitmap); 192 std::move(callback).Run(emptyBitmap);
220 return; 193 return;
221 } 194 }
222 195
223 blink::WebImage image = static_cast<blink::WebMockClipboard*>( 196 blink::WebImage image = static_cast<blink::WebMockClipboard*>(
224 blink::Platform::Current()->Clipboard()) 197 blink::Platform::Current()->Clipboard())
225 ->ReadRawImage(blink::WebClipboard::Buffer()); 198 ->ReadRawImage(blink::WebClipboard::Buffer());
226 callback.Run(image.GetSkBitmap()); 199 std::move(callback).Run(image.GetSkBitmap());
227 } 200 }
228 201
229 } // namespace test_runner 202 } // namespace test_runner
OLDNEW
« no previous file with comments | « content/shell/test_runner/pixel_dump.h ('k') | content/shell/test_runner/test_runner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698