Commit e9f67451 authored by danakj's avatar danakj Committed by Commit Bot

Simplify and make BlinkTestRunner::CaptureLocalPixelsDump synchronous.

Remove some async callbacks that are not needed in the renderer side
test completion path. This is toward pushing test completion code up
to the browser so we don't depend on keeping a stable renderer main
frame across navigations, which RenderDocument changes.

R=avi@chromium.org

Bug: 866140, 1069111
Change-Id: Ia73ab3ec79ec2a226fc26a92c65962355ff6e1fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2284373Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#785926}
parent d3f338a0
...@@ -140,31 +140,12 @@ void BlinkTestRunner::CaptureLocalPixelsDump() { ...@@ -140,31 +140,12 @@ void BlinkTestRunner::CaptureLocalPixelsDump() {
// with the current, non-swapped-out RenderView. // with the current, non-swapped-out RenderView.
DCHECK(web_view_test_proxy_->GetMainRenderFrame()); DCHECK(web_view_test_proxy_->GetMainRenderFrame());
waiting_for_pixels_dump_result_ = true;
TestRunner* test_runner = web_view_test_proxy_->GetTestRunner(); TestRunner* test_runner = web_view_test_proxy_->GetTestRunner();
test_runner->DumpPixelsAsync( SkBitmap snapshot = test_runner->DumpPixelsInRenderer(web_view_test_proxy_);
web_view_test_proxy_,
base::BindOnce(&BlinkTestRunner::OnPixelsDumpCompleted,
base::Unretained(this)));
}
void BlinkTestRunner::OnLayoutDumpCompleted(std::string completed_layout_dump) {
CHECK(waiting_for_layout_dump_results_);
dump_result_->layout.emplace(completed_layout_dump);
waiting_for_layout_dump_results_ = false;
CaptureDumpComplete();
}
void BlinkTestRunner::OnPixelsDumpCompleted(const SkBitmap& snapshot) { DCHECK_GT(snapshot.info().width(), 0);
CHECK(waiting_for_pixels_dump_result_); DCHECK_GT(snapshot.info().height(), 0);
DCHECK_NE(0, snapshot.info().width());
DCHECK_NE(0, snapshot.info().height());
// The snapshot arrives from the GPU process via shared memory. Because MSan
// can't track initializedness across processes, we must assure it that the
// pixels are in fact initialized.
MSAN_UNPOISON(snapshot.getPixels(), snapshot.computeByteSize());
base::MD5Digest digest; base::MD5Digest digest;
base::MD5Sum(snapshot.getPixels(), snapshot.computeByteSize(), &digest); base::MD5Sum(snapshot.getPixels(), snapshot.computeByteSize(), &digest);
std::string actual_pixel_hash = base::MD5DigestToBase16(digest); std::string actual_pixel_hash = base::MD5DigestToBase16(digest);
...@@ -173,13 +154,19 @@ void BlinkTestRunner::OnPixelsDumpCompleted(const SkBitmap& snapshot) { ...@@ -173,13 +154,19 @@ void BlinkTestRunner::OnPixelsDumpCompleted(const SkBitmap& snapshot) {
if (actual_pixel_hash != test_config_->expected_pixel_hash) if (actual_pixel_hash != test_config_->expected_pixel_hash)
dump_result_->pixels = snapshot; dump_result_->pixels = snapshot;
waiting_for_pixels_dump_result_ = false; CaptureDumpComplete();
}
void BlinkTestRunner::OnLayoutDumpCompleted(std::string completed_layout_dump) {
CHECK(waiting_for_layout_dump_results_);
dump_result_->layout.emplace(completed_layout_dump);
waiting_for_layout_dump_results_ = false;
CaptureDumpComplete(); CaptureDumpComplete();
} }
void BlinkTestRunner::CaptureDumpComplete() { void BlinkTestRunner::CaptureDumpComplete() {
// Abort if we're still waiting for some results. // Abort if we're still waiting for some results.
if (waiting_for_layout_dump_results_ || waiting_for_pixels_dump_result_) if (waiting_for_layout_dump_results_)
return; return;
// Abort if the browser didn't ask us for the dump yet. // Abort if the browser didn't ask us for the dump yet.
......
...@@ -97,7 +97,6 @@ class BlinkTestRunner { ...@@ -97,7 +97,6 @@ class BlinkTestRunner {
mojom::WebTestRenderFrame::CaptureDumpCallback dump_callback_; mojom::WebTestRenderFrame::CaptureDumpCallback dump_callback_;
mojom::WebTestDumpPtr dump_result_; mojom::WebTestDumpPtr dump_result_;
bool waiting_for_layout_dump_results_ = false; bool waiting_for_layout_dump_results_ = false;
bool waiting_for_pixels_dump_result_ = false;
DISALLOW_COPY_AND_ASSIGN(BlinkTestRunner); DISALLOW_COPY_AND_ASSIGN(BlinkTestRunner);
}; };
......
...@@ -40,11 +40,7 @@ ...@@ -40,11 +40,7 @@
namespace content { namespace content {
namespace { SkBitmap PrintFrameToBitmap(blink::WebLocalFrame* web_frame) {
void CapturePixelsForPrinting(
blink::WebLocalFrame* web_frame,
base::OnceCallback<void(const SkBitmap&)> callback) {
auto* frame_widget = web_frame->LocalRoot()->FrameWidget(); auto* frame_widget = web_frame->LocalRoot()->FrameWidget();
frame_widget->UpdateAllLifecyclePhases(blink::DocumentUpdateReason::kTest); frame_widget->UpdateAllLifecyclePhases(blink::DocumentUpdateReason::kTest);
...@@ -61,8 +57,7 @@ void CapturePixelsForPrinting( ...@@ -61,8 +57,7 @@ void CapturePixelsForPrinting(
is_opaque)) { is_opaque)) {
LOG(ERROR) << "Failed to create bitmap width=" << page_size_in_pixels.width LOG(ERROR) << "Failed to create bitmap width=" << page_size_in_pixels.width
<< " height=" << spool_size.height; << " height=" << spool_size.height;
std::move(callback).Run(SkBitmap()); return SkBitmap();
return;
} }
printing::MetafileSkia metafile(printing::mojom::SkiaDocumentType::kMSKP, printing::MetafileSkia metafile(printing::mojom::SkiaDocumentType::kMSKP,
...@@ -71,20 +66,7 @@ void CapturePixelsForPrinting( ...@@ -71,20 +66,7 @@ void CapturePixelsForPrinting(
canvas.SetPrintingMetafile(&metafile); canvas.SetPrintingMetafile(&metafile);
web_frame->PrintPagesForTesting(&canvas, page_size_in_pixels, spool_size); web_frame->PrintPagesForTesting(&canvas, page_size_in_pixels, spool_size);
web_frame->PrintEnd(); web_frame->PrintEnd();
return bitmap;
std::move(callback).Run(bitmap);
}
} // namespace
void PrintFrameAsync(blink::WebLocalFrame* web_frame,
base::OnceCallback<void(const SkBitmap&)> callback) {
DCHECK(web_frame);
DCHECK(callback);
web_frame->GetTaskRunner(blink::TaskType::kInternalTest)
->PostTask(FROM_HERE, base::BindOnce(&CapturePixelsForPrinting,
base::Unretained(web_frame),
std::move(callback)));
} }
} // namespace content } // namespace content
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_PIXEL_DUMP_H_ #ifndef CONTENT_SHELL_RENDERER_WEB_TEST_PIXEL_DUMP_H_
#define CONTENT_SHELL_RENDERER_WEB_TEST_PIXEL_DUMP_H_ #define CONTENT_SHELL_RENDERER_WEB_TEST_PIXEL_DUMP_H_
#include "base/callback_forward.h"
class SkBitmap; class SkBitmap;
namespace blink { namespace blink {
...@@ -15,9 +13,9 @@ class WebLocalFrame; ...@@ -15,9 +13,9 @@ class WebLocalFrame;
namespace content { namespace content {
// Asks |web_frame| to print itself and calls |callback| with the result. // Goes through a test-only path to dump the frame's pixel output as if it was
void PrintFrameAsync(blink::WebLocalFrame* web_frame, // printed.
base::OnceCallback<void(const SkBitmap&)> callback); SkBitmap PrintFrameToBitmap(blink::WebLocalFrame* web_frame);
} // namespace content } // namespace content
......
...@@ -1871,33 +1871,24 @@ void TestRunnerBindings::GetManifestThen(v8::Local<v8::Function> v8_callback) { ...@@ -1871,33 +1871,24 @@ void TestRunnerBindings::GetManifestThen(v8::Local<v8::Function> v8_callback) {
base::BindOnce(GetManifestReply, WrapV8Callback(std::move(v8_callback)))); base::BindOnce(GetManifestReply, WrapV8Callback(std::move(v8_callback))));
} }
static void CapturePrintingPixelsThenReply( void TestRunnerBindings::CapturePrintingPixelsThen(
base::WeakPtr<TestRunnerBindings> test_runner, v8::Local<v8::Function> v8_callback) {
blink::WebLocalFrame* frame, if (invalid_)
BoundV8Callback callback,
const SkBitmap& bitmap) {
if (!test_runner) // This guards the validity of the |frame|.
return; return;
SkBitmap bitmap = PrintFrameToBitmap(GetWebFrame());
v8::Isolate* isolate = blink::MainThreadIsolate(); v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
// ConvertBitmapToV8() requires a v8::Context. // ConvertBitmapToV8() requires a v8::Context.
v8::Local<v8::Context> context = frame->MainWorldScriptContext(); v8::Local<v8::Context> context = GetWebFrame()->MainWorldScriptContext();
CHECK(!context.IsEmpty()); CHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
std::move(callback).Run(ConvertBitmapToV8(context_scope, bitmap)); WrapV8Callback(std::move(v8_callback))
} .Run({
ConvertBitmapToV8(context_scope, bitmap),
void TestRunnerBindings::CapturePrintingPixelsThen( });
v8::Local<v8::Function> v8_callback) {
if (invalid_)
return;
PrintFrameAsync(GetWebFrame(),
base::BindOnce(&CapturePrintingPixelsThenReply,
weak_ptr_factory_.GetWeakPtr(), GetWebFrame(),
WrapV8Callback(std::move(v8_callback))));
} }
void TestRunnerBindings::CheckForLeakedWindows() { void TestRunnerBindings::CheckForLeakedWindows() {
...@@ -2368,25 +2359,21 @@ bool TestRunner::CanDumpPixelsFromRenderer() const { ...@@ -2368,25 +2359,21 @@ bool TestRunner::CanDumpPixelsFromRenderer() const {
web_test_runtime_flags_.is_printing(); web_test_runtime_flags_.is_printing();
} }
void TestRunner::DumpPixelsAsync( SkBitmap TestRunner::DumpPixelsInRenderer(content::RenderView* render_view) {
content::RenderView* render_view,
base::OnceCallback<void(const SkBitmap&)> callback) {
auto* view_proxy = static_cast<WebViewTestProxy*>(render_view); auto* view_proxy = static_cast<WebViewTestProxy*>(render_view);
DCHECK(view_proxy->GetWebView()->MainFrame()); DCHECK(view_proxy->GetWebView()->MainFrame());
DCHECK(CanDumpPixelsFromRenderer()); DCHECK(CanDumpPixelsFromRenderer());
if (web_test_runtime_flags_.dump_drag_image()) { if (web_test_runtime_flags_.dump_drag_image()) {
if (!drag_image_.isNull()) { if (!drag_image_.isNull())
std::move(callback).Run(drag_image_); return drag_image_;
} else {
// This means the test called dumpDragImage but did not initiate a drag. // This means the test called dumpDragImage but did not initiate a drag.
// Return a blank image so that the test fails. // Return a blank image so that the test fails.
SkBitmap bitmap; SkBitmap bitmap;
bitmap.allocN32Pixels(1, 1); bitmap.allocN32Pixels(1, 1);
bitmap.eraseColor(0); bitmap.eraseColor(0);
std::move(callback).Run(bitmap); return bitmap;
}
return;
} }
blink::WebLocalFrame* frame = blink::WebLocalFrame* frame =
...@@ -2399,7 +2386,7 @@ void TestRunner::DumpPixelsAsync( ...@@ -2399,7 +2386,7 @@ void TestRunner::DumpPixelsAsync(
if (frame_to_print && frame_to_print->IsWebLocalFrame()) if (frame_to_print && frame_to_print->IsWebLocalFrame())
target_frame = frame_to_print->ToWebLocalFrame(); target_frame = frame_to_print->ToWebLocalFrame();
} }
PrintFrameAsync(target_frame, std::move(callback)); return PrintFrameToBitmap(target_frame);
} }
void TestRunner::ReplicateWebTestRuntimeFlagsChanges( void TestRunner::ReplicateWebTestRuntimeFlagsChanges(
......
...@@ -138,14 +138,13 @@ class TestRunner { ...@@ -138,14 +138,13 @@ class TestRunner {
bool ShouldDumpSelectionRect() const; bool ShouldDumpSelectionRect() const;
// Returns false if the browser should capture the pixel output, true if it // Returns false if the browser should capture the pixel output, true if it
// can be done locally in the renderer via DumpPixelsAsync(). // can be done locally in the renderer via DumpPixelsInRenderer().
bool CanDumpPixelsFromRenderer() const; bool CanDumpPixelsFromRenderer() const;
// Snapshots the content of |render_view| using the mode requested by the // Snapshots the content of |render_view| using the mode requested by the
// current test and calls |callback| with the result. Caller needs to ensure // current test and calls |callback| with the result. Caller needs to ensure
// that |render_view| stays alive until |callback| is called. // that |render_view| stays alive until |callback| is called.
void DumpPixelsAsync(content::RenderView* render_view, SkBitmap DumpPixelsInRenderer(content::RenderView* render_view);
base::OnceCallback<void(const SkBitmap&)> callback);
// Replicates changes to web test runtime flags (i.e. changes that happened in // Replicates changes to web test runtime flags (i.e. changes that happened in
// another renderer). See also BlinkTestRunner::OnWebTestRuntimeFlagsChanged. // another renderer). See also BlinkTestRunner::OnWebTestRuntimeFlagsChanged.
......
...@@ -43,7 +43,8 @@ function nextTest() { ...@@ -43,7 +43,8 @@ function nextTest() {
var color = test['clearColor']; var color = test['clearColor'];
try { try {
draw(color[0], color[1], color[2], color[3]); draw(color[0], color[1], color[2], color[3]);
testRunner.capturePrintingPixelsThen(completionCallback); testRunner.updateAllLifecyclePhasesAndCompositeThen(
()=>testRunner.capturePrintingPixelsThen(completionCallback));
} catch (e) { } catch (e) {
debug('error in nextTest'); debug('error in nextTest');
debug(e); debug(e);
......
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