Commit 43ea25e3 authored by enne@chromium.org's avatar enne@chromium.org

Make WindowReachedScreen support async readback

This is the final caller that doesn't fall back or is Aura-only, and so
Aura's snapshot can switch over to only being asynchronous.

BUG=332167

Review URL: https://codereview.chromium.org/127103002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245354 0039d316-1c4b-4281-b951-d872f2087c98
parent d4df5dbb
......@@ -20,6 +20,7 @@
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
......@@ -2432,6 +2433,22 @@ void RenderWidgetHostImpl::DidReceiveRendererFrame() {
view_->DidReceiveRendererFrame();
}
void RenderWidgetHostImpl::WindowSnapshotAsyncCallback(
int routing_id,
int snapshot_id,
gfx::Size snapshot_size,
scoped_refptr<base::RefCountedBytes> png_data) {
if (!png_data) {
std::vector<unsigned char> png_vector;
Send(new ViewMsg_WindowSnapshotCompleted(
routing_id, snapshot_id, gfx::Size(), png_vector));
return;
}
Send(new ViewMsg_WindowSnapshotCompleted(
routing_id, snapshot_id, snapshot_size, png_data->data()));
}
void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) {
DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_UI));
......@@ -2440,21 +2457,32 @@ void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) {
// This feature is behind the kEnableGpuBenchmarking command line switch
// because it poses security concerns and should only be used for testing.
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kEnableGpuBenchmarking)) {
gfx::Rect view_bounds = GetView()->GetViewBounds();
gfx::Rect snapshot_bounds(view_bounds.size());
gfx::Size snapshot_size = snapshot_bounds.size();
if (ui::GrabViewSnapshot(GetView()->GetNativeView(),
&png, snapshot_bounds)) {
Send(new ViewMsg_WindowSnapshotCompleted(
GetRoutingID(), snapshot_id, snapshot_size, png));
return;
}
if (!command_line.HasSwitch(switches::kEnableGpuBenchmarking)) {
Send(new ViewMsg_WindowSnapshotCompleted(
GetRoutingID(), snapshot_id, gfx::Size(), png));
return;
}
Send(new ViewMsg_WindowSnapshotCompleted(
GetRoutingID(), snapshot_id, gfx::Size(), png));
gfx::Rect view_bounds = GetView()->GetViewBounds();
gfx::Rect snapshot_bounds(view_bounds.size());
gfx::Size snapshot_size = snapshot_bounds.size();
if (ui::GrabViewSnapshot(
GetView()->GetNativeView(), &png, snapshot_bounds)) {
Send(new ViewMsg_WindowSnapshotCompleted(
GetRoutingID(), snapshot_id, snapshot_size, png));
return;
}
ui::GrabViewSnapshotAsync(
GetView()->GetNativeView(),
snapshot_bounds,
base::ThreadTaskRunnerHandle::Get(),
base::Bind(&RenderWidgetHostImpl::WindowSnapshotAsyncCallback,
weak_factory_.GetWeakPtr(),
GetRoutingID(),
snapshot_id,
snapshot_size));
}
// static
......
......@@ -544,6 +544,12 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// Don't check whether we expected a resize ack during layout tests.
static void DisableResizeAckCheckForTesting();
void WindowSnapshotAsyncCallback(
int routing_id,
int snapshot_id,
gfx::Size snapshot_size,
scoped_refptr<base::RefCountedBytes> png_data);
protected:
virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() OVERRIDE;
......
......@@ -28,8 +28,9 @@ namespace ui {
// Grabs a snapshot of the window/view. No security checks are done. This is
// intended to be used for debugging purposes where no BrowserProcess instance
// is available (ie. tests). This function is synchronous, so it should NOT be
// used in a result of user action. Use asynchronous GrabWindowSnapshotAsync()
// instead on supported platforms.
// used in a result of user action. Support for async vs synchronous
// GrabWindowSnapshot differs by platform. To be most general, use the
// synchronous function first and if it returns false call the async one.
SNAPSHOT_EXPORT bool GrabWindowSnapshot(
gfx::NativeWindow window,
std::vector<unsigned char>* png_representation,
......@@ -58,6 +59,11 @@ SNAPSHOT_EXPORT void GrabWindowSnapshotAsync(
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback);
SNAPSHOT_EXPORT void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback);
} // namespace ui
......
......@@ -8,6 +8,7 @@
#include "ui/base/android/view_android.h"
#include "ui/base/android/window_android.h"
#include "ui/gfx/display.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
......@@ -39,7 +40,15 @@ void GrabWindowSnapshotAndScaleAsync(
const gfx::Size& target_size,
scoped_refptr<base::TaskRunner> background_task_runner,
GrabWindowSnapshotAsyncCallback callback) {
NOTIMPLEMENTED();
callback.Run(gfx::Image());
}
void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
void GrabWindowSnapshotAsync(
......@@ -47,7 +56,7 @@ void GrabWindowSnapshotAsync(
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
NOTIMPLEMENTED();
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
} // namespace ui
......@@ -177,26 +177,8 @@ bool GrabViewSnapshot(gfx::NativeView view,
bool GrabWindowSnapshot(gfx::NativeWindow window,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds) {
gfx::Rect read_pixels_bounds_in_pixel =
GetTargetBoundsFromWindow(window, snapshot_bounds);
ui::Compositor* compositor = window->layer()->GetCompositor();
SkBitmap bitmap;
if (!compositor->ReadPixels(&bitmap, read_pixels_bounds_in_pixel))
return false;
gfx::Display display =
gfx::Screen::GetScreenFor(window)->GetDisplayNearestWindow(window);
RotateBitmap(&bitmap, display.rotation());
unsigned char* pixels = reinterpret_cast<unsigned char*>(
bitmap.pixelRef()->pixels());
return gfx::PNGCodec::Encode(
pixels, gfx::PNGCodec::FORMAT_BGRA,
gfx::Size(bitmap.width(), bitmap.height()),
base::checked_numeric_cast<int>(bitmap.rowBytes()),
true, std::vector<gfx::PNGCodec::Comment>(),
png_representation);
// Not supported in Aura. Callers should fall back to the async version.
return false;
}
void MakeAsyncCopyRequest(
......@@ -261,4 +243,13 @@ void GrabWindowSnapshotAsync(
background_task_runner));
}
void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
GrabWindowSnapshotAsync(view, source_rect, background_task_runner, callback);
}
} // namespace ui
......@@ -60,7 +60,7 @@ size_t GetFailedPixelsCount(const gfx::Image& image) {
} // namespace
class SnapshotAuraTest : public testing::TestWithParam<bool> {
class SnapshotAuraTest : public testing::Test {
public:
SnapshotAuraTest() {}
virtual ~SnapshotAuraTest() {}
......@@ -99,16 +99,8 @@ class SnapshotAuraTest : public testing::TestWithParam<bool> {
delegate_.get(), 0, window_bounds, root_window()));
}
bool is_async_test() const { return GetParam(); }
gfx::Image GrabSnapshotForTestWindow() {
gfx::Rect source_rect(test_window_->bounds().size());
if (!is_async_test()) {
std::vector<unsigned char> png_representation;
ui::GrabWindowSnapshot(test_window(), &png_representation, source_rect);
return gfx::Image::CreateFrom1xPNGBytes(&(png_representation[0]),
png_representation.size());
}
scoped_refptr<base::TestSimpleTaskRunner> task_runner(
new base::TestSimpleTaskRunner());
......@@ -167,9 +159,7 @@ class SnapshotAuraTest : public testing::TestWithParam<bool> {
DISALLOW_COPY_AND_ASSIGN(SnapshotAuraTest);
};
INSTANTIATE_TEST_CASE_P(SnapshotAuraTest, SnapshotAuraTest, ::testing::Bool());
TEST_P(SnapshotAuraTest, FullScreenWindow) {
TEST_F(SnapshotAuraTest, FullScreenWindow) {
SetupTestWindow(root_window()->bounds());
WaitForDraw();
......@@ -179,7 +169,7 @@ TEST_P(SnapshotAuraTest, FullScreenWindow) {
EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
}
TEST_P(SnapshotAuraTest, PartialBounds) {
TEST_F(SnapshotAuraTest, PartialBounds) {
gfx::Rect test_bounds(100, 100, 300, 200);
SetupTestWindow(test_bounds);
WaitForDraw();
......@@ -190,7 +180,7 @@ TEST_P(SnapshotAuraTest, PartialBounds) {
EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
}
TEST_P(SnapshotAuraTest, Rotated) {
TEST_F(SnapshotAuraTest, Rotated) {
test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
gfx::Rect test_bounds(100, 100, 300, 200);
......@@ -203,7 +193,7 @@ TEST_P(SnapshotAuraTest, Rotated) {
EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
}
TEST_P(SnapshotAuraTest, UIScale) {
TEST_F(SnapshotAuraTest, UIScale) {
const float kUIScale = 1.25f;
test_screen()->SetUIScale(kUIScale);
......@@ -221,7 +211,7 @@ TEST_P(SnapshotAuraTest, UIScale) {
EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
}
TEST_P(SnapshotAuraTest, DeviceScaleFactor) {
TEST_F(SnapshotAuraTest, DeviceScaleFactor) {
test_screen()->SetDeviceScaleFactor(2.0f);
gfx::Rect test_bounds(100, 100, 150, 100);
......@@ -238,7 +228,7 @@ TEST_P(SnapshotAuraTest, DeviceScaleFactor) {
EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
}
TEST_P(SnapshotAuraTest, RotateAndUIScale) {
TEST_F(SnapshotAuraTest, RotateAndUIScale) {
const float kUIScale = 1.25f;
test_screen()->SetUIScale(kUIScale);
test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
......@@ -257,7 +247,7 @@ TEST_P(SnapshotAuraTest, RotateAndUIScale) {
EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
}
TEST_P(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) {
TEST_F(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) {
test_screen()->SetDeviceScaleFactor(2.0f);
const float kUIScale = 1.25f;
test_screen()->SetUIScale(kUIScale);
......
......@@ -10,6 +10,7 @@
#include "base/callback.h"
#include "base/logging.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
namespace {
......@@ -89,7 +90,15 @@ void GrabWindowSnapshotAndScaleAsync(
const gfx::Size& target_size,
scoped_refptr<base::TaskRunner> background_task_runner,
GrabWindowSnapshotAsyncCallback callback) {
NOTIMPLEMENTED();
callback.Run(gfx::Image());
}
void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
void GrabWindowSnapshotAsync(
......@@ -97,7 +106,7 @@ void GrabWindowSnapshotAsync(
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
NOTIMPLEMENTED();
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
} // namespace ui
......@@ -5,6 +5,7 @@
#include "ui/snapshot/snapshot.h"
#include "base/callback.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
namespace ui {
......@@ -29,7 +30,15 @@ void GrabWindowSnapshotAndScaleAsync(
const gfx::Size& target_size,
scoped_refptr<base::TaskRunner> background_task_runner,
GrabWindowSnapshotAsyncCallback callback) {
NOTIMPLEMENTED();
callback.Run(gfx::Image());
}
void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
void GrabWindowSnapshotAsync(
......@@ -37,7 +46,7 @@ void GrabWindowSnapshotAsync(
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
NOTIMPLEMENTED();
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
} // namespace ui
......@@ -10,6 +10,8 @@
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "base/task_runner.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
namespace ui {
......@@ -79,7 +81,15 @@ void GrabWindowSnapshotAndScaleAsync(
const gfx::Size& target_size,
scoped_refptr<base::TaskRunner> background_task_runner,
GrabWindowSnapshotAsyncCallback callback) {
NOTIMPLEMENTED();
callback.Run(gfx::Image());
}
void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
void GrabWindowSnapshotAsync(
......@@ -87,7 +97,8 @@ void GrabWindowSnapshotAsync(
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
NOTIMPLEMENTED();
return GrabViewSnapshotAsync([[window contentView] superview], source_rect,
background_task_runner, callback);
}
} // namespace ui
......@@ -125,15 +125,24 @@ void GrapWindowSnapshotAsync(
const gfx::Size& target_size,
scoped_refptr<base::TaskRunner> background_task_runner,
GrabWindowSnapshotAsyncCallback callback) {
NOTIMPLEMENTED();
callback.Run(gfx::Image());
}
void GrabViewSnapshotAsync(
gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
void GrabWindowSnapshotAsync(
gfx::NativeWindow window,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
NOTIMPLEMENTED();
callback.Run(scoped_refptr<base::RefCountedBytes>());
}
#endif // !defined(USE_AURA)
......
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