Commit 5a74271d authored by pfeldman@chromium.org's avatar pfeldman@chromium.org

DevTools: backend part of the color picker (behind experiment).

NOTRY=true
BUG=404375

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

Cr-Commit-Position: refs/heads/master@{#290185}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290185 0039d316-1c4b-4281-b951-d872f2087c98
parent 241016ef
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/cursors/webcursor.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
...@@ -40,8 +42,10 @@ ...@@ -40,8 +42,10 @@
#include "content/public/common/referrer.h" #include "content/public/common/referrer.h"
#include "ipc/ipc_sender.h" #include "ipc/ipc_sender.h"
#include "net/base/net_util.h" #include "net/base/net_util.h"
#include "third_party/WebKit/public/platform/WebCursorInfo.h"
#include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h"
#include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h" #include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/display.h" #include "ui/gfx/display.h"
...@@ -70,6 +74,7 @@ static int kCaptureRetryLimit = 2; ...@@ -70,6 +74,7 @@ static int kCaptureRetryLimit = 2;
RendererOverridesHandler::RendererOverridesHandler() RendererOverridesHandler::RendererOverridesHandler()
: has_last_compositor_frame_metadata_(false), : has_last_compositor_frame_metadata_(false),
capture_retry_count_(0), capture_retry_count_(0),
color_picker_enabled_(false),
weak_factory_(this) { weak_factory_(this) {
RegisterCommandHandler( RegisterCommandHandler(
devtools::DOM::setFileInputFiles::kName, devtools::DOM::setFileInputFiles::kName,
...@@ -140,11 +145,19 @@ RendererOverridesHandler::RendererOverridesHandler() ...@@ -140,11 +145,19 @@ RendererOverridesHandler::RendererOverridesHandler()
base::Bind( base::Bind(
&RendererOverridesHandler::PageQueryUsageAndQuota, &RendererOverridesHandler::PageQueryUsageAndQuota,
base::Unretained(this))); base::Unretained(this)));
RegisterCommandHandler(
devtools::Page::setColorPickerEnabled::kName,
base::Bind(
&RendererOverridesHandler::PageSetColorPickerEnabled,
base::Unretained(this)));
RegisterCommandHandler( RegisterCommandHandler(
devtools::Input::emulateTouchFromMouseEvent::kName, devtools::Input::emulateTouchFromMouseEvent::kName,
base::Bind( base::Bind(
&RendererOverridesHandler::InputEmulateTouchFromMouseEvent, &RendererOverridesHandler::InputEmulateTouchFromMouseEvent,
base::Unretained(this))); base::Unretained(this)));
mouse_event_callback_ = base::Bind(
&RendererOverridesHandler::HandleMouseEvent,
base::Unretained(this));
} }
RendererOverridesHandler::~RendererOverridesHandler() {} RendererOverridesHandler::~RendererOverridesHandler() {}
...@@ -153,6 +166,7 @@ void RendererOverridesHandler::OnClientDetached() { ...@@ -153,6 +166,7 @@ void RendererOverridesHandler::OnClientDetached() {
if (screencast_command_ && host_) if (screencast_command_ && host_)
host_->SetTouchEventEmulationEnabled(false, false); host_->SetTouchEventEmulationEnabled(false, false);
screencast_command_ = NULL; screencast_command_ = NULL;
SetColorPickerEnabled(false);
} }
void RendererOverridesHandler::OnSwapCompositorFrame( void RendererOverridesHandler::OnSwapCompositorFrame(
...@@ -162,6 +176,8 @@ void RendererOverridesHandler::OnSwapCompositorFrame( ...@@ -162,6 +176,8 @@ void RendererOverridesHandler::OnSwapCompositorFrame(
if (screencast_command_) if (screencast_command_)
InnerSwapCompositorFrame(); InnerSwapCompositorFrame();
if (color_picker_enabled_)
UpdateColorPickerFrame();
} }
void RendererOverridesHandler::OnVisibilityChanged(bool visible) { void RendererOverridesHandler::OnVisibilityChanged(bool visible) {
...@@ -175,9 +191,13 @@ void RendererOverridesHandler::SetRenderViewHost( ...@@ -175,9 +191,13 @@ void RendererOverridesHandler::SetRenderViewHost(
host_ = host; host_ = host;
if (screencast_command_ && host) if (screencast_command_ && host)
host->SetTouchEventEmulationEnabled(true, true); host->SetTouchEventEmulationEnabled(true, true);
if (color_picker_enabled_)
host->AddMouseEventCallback(mouse_event_callback_);
} }
void RendererOverridesHandler::ClearRenderViewHost() { void RendererOverridesHandler::ClearRenderViewHost() {
if (host_)
host_->RemoveMouseEventCallback(mouse_event_callback_);
host_ = NULL; host_ = NULL;
} }
...@@ -847,6 +867,204 @@ void RendererOverridesHandler::NotifyScreencastVisibility(bool visible) { ...@@ -847,6 +867,204 @@ void RendererOverridesHandler::NotifyScreencastVisibility(bool visible) {
devtools::Page::screencastVisibilityChanged::kName, params); devtools::Page::screencastVisibilityChanged::kName, params);
} }
scoped_refptr<DevToolsProtocol::Response>
RendererOverridesHandler::PageSetColorPickerEnabled(
scoped_refptr<DevToolsProtocol::Command> command) {
base::DictionaryValue* params = command->params();
bool color_picker_enabled = false;
if (!params || !params->GetBoolean(
devtools::Page::setColorPickerEnabled::kParamEnabled,
&color_picker_enabled)) {
return command->InvalidParamResponse(
devtools::Page::setColorPickerEnabled::kParamEnabled);
}
SetColorPickerEnabled(color_picker_enabled);
return command->SuccessResponse(NULL);
}
void RendererOverridesHandler::SetColorPickerEnabled(bool enabled) {
if (color_picker_enabled_ == enabled)
return;
color_picker_enabled_ = enabled;
if (!host_)
return;
if (enabled) {
host_->AddMouseEventCallback(mouse_event_callback_);
UpdateColorPickerFrame();
} else {
host_->RemoveMouseEventCallback(mouse_event_callback_);
color_picker_frame_.reset();
WebCursor pointer_cursor;
WebCursor::CursorInfo cursor_info;
cursor_info.type = blink::WebCursorInfo::TypePointer;
pointer_cursor.InitFromCursorInfo(cursor_info);
host_->SetCursor(pointer_cursor);
}
}
void RendererOverridesHandler::UpdateColorPickerFrame() {
if (!host_)
return;
RenderWidgetHostViewBase* view =
static_cast<RenderWidgetHostViewBase*>(host_->GetView());
if (!view)
return;
gfx::Size size = view->GetViewBounds().size();
view->CopyFromCompositingSurface(
gfx::Rect(size), size,
base::Bind(&RendererOverridesHandler::ColorPickerFrameUpdated,
weak_factory_.GetWeakPtr()),
kN32_SkColorType);
}
void RendererOverridesHandler::ColorPickerFrameUpdated(
bool succeeded,
const SkBitmap& bitmap) {
if (succeeded)
color_picker_frame_ = bitmap;
}
bool RendererOverridesHandler::HandleMouseEvent(
const blink::WebMouseEvent& event) {
if (color_picker_frame_.drawsNothing())
return true;
if (event.button == blink::WebMouseEvent::ButtonLeft) {
color_picker_frame_.lockPixels();
SkColor color = color_picker_frame_.getColor(event.x, event.y);
color_picker_frame_.unlockPixels();
base::DictionaryValue* color_dict = new base::DictionaryValue();
color_dict->SetInteger("r", SkColorGetR(color));
color_dict->SetInteger("g", SkColorGetG(color));
color_dict->SetInteger("b", SkColorGetB(color));
color_dict->SetInteger("a", SkColorGetA(color));
base::DictionaryValue* response = new base::DictionaryValue();
response->Set(devtools::Page::colorPicked::kParamColor, color_dict);
SendNotification(devtools::Page::colorPicked::kName, response);
}
if (!host_)
return true;
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
host_->GetView());
if (!view)
return true;
// Due to platform limitations, we are using two different cursors
// depending on the platform. Mac and Win have large cursors with two circles
// for original spot and its magnified projection; Linux gets smaller (64 px)
// magnified projection only with centered hotspot.
// Mac Retina requires cursor to be > 120px in order to render smoothly.
#if defined(OS_LINUX)
const float kCursorSize = 63;
const float kDiameter = 63;
const float kHotspotOffset = 32;
const float kHotspotRadius = 0;
const float kPixelSize = 9;
#else
const float kCursorSize = 150;
const float kDiameter = 110;
const float kHotspotOffset = 25;
const float kHotspotRadius = 5;
const float kPixelSize = 10;
#endif
const float kSqrt2 = 1.41f;
blink::WebScreenInfo screen_info;
view->GetScreenInfo(&screen_info);
double device_scale_factor = screen_info.deviceScaleFactor;
skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(SkCanvas::NewRasterN32(
kCursorSize * device_scale_factor,
kCursorSize * device_scale_factor));
canvas->scale(device_scale_factor, device_scale_factor);
SkPaint paint;
// Paint original spot.
if (kHotspotRadius) {
paint.setStrokeWidth(2);
paint.setColor(SK_ColorDKGRAY);
paint.setStyle(SkPaint::kStroke_Style);
paint.setAntiAlias(true);
canvas->drawCircle(kHotspotOffset, kHotspotOffset, kHotspotRadius, paint);
canvas->drawLine(kHotspotOffset + kHotspotRadius / kSqrt2,
kHotspotOffset + kHotspotRadius / kSqrt2,
kCursorSize / 2, kCursorSize / 2,
paint);
}
// Clip circle for magnified projection.
float padding = (kCursorSize - kDiameter) / 2;
SkPath clip_path;
clip_path.addOval(SkRect::MakeXYWH(padding, padding, kDiameter, kDiameter));
clip_path.close();
canvas->clipPath(clip_path, SkRegion::kIntersect_Op, true);
// Project pixels.
int pixel_count = kDiameter / kPixelSize;
SkRect src_rect = SkRect::MakeXYWH(event.x - pixel_count / 2,
event.y - pixel_count / 2,
pixel_count, pixel_count);
SkRect dst_rect = SkRect::MakeXYWH(padding, padding, kDiameter, kDiameter);
canvas->drawBitmapRectToRect(color_picker_frame_, &src_rect, dst_rect);
// Paint grid.
paint.setStrokeWidth(1);
paint.setAntiAlias(false);
paint.setColor(SK_ColorGRAY);
for (int i = 0; i < pixel_count; ++i) {
canvas->drawLine(padding + i * kPixelSize, padding,
padding + i * kPixelSize, kCursorSize - padding, paint);
canvas->drawLine(padding, padding + i * kPixelSize,
kCursorSize - padding, padding + i * kPixelSize, paint);
}
// Paint central pixel in red.
SkRect pixel = SkRect::MakeXYWH((kCursorSize - kPixelSize) / 2,
(kCursorSize - kPixelSize) / 2,
kPixelSize, kPixelSize);
paint.setColor(SK_ColorRED);
canvas->drawRect(pixel, paint);
// Paint outline.
paint.setStrokeWidth(2);
paint.setColor(SK_ColorDKGRAY);
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawCircle(kCursorSize / 2, kCursorSize / 2, kDiameter / 2, paint);
SkBitmap result;
result.allocN32Pixels(kCursorSize * device_scale_factor,
kCursorSize * device_scale_factor);
canvas->readPixels(&result, 0, 0);
WebCursor cursor;
WebCursor::CursorInfo cursor_info;
cursor_info.type = blink::WebCursorInfo::TypeCustom;
cursor_info.image_scale_factor = device_scale_factor;
cursor_info.custom_image = result;
cursor_info.hotspot =
gfx::Point(kHotspotOffset * device_scale_factor,
kHotspotOffset * device_scale_factor);
#if defined(OS_WIN)
cursor_info.external_handle = 0;
#endif
cursor.InitFromCursorInfo(cursor_info);
DCHECK(host_);
host_->SetCursor(cursor);
return true;
}
// Input agent handlers ------------------------------------------------------ // Input agent handlers ------------------------------------------------------
scoped_refptr<DevToolsProtocol::Response> scoped_refptr<DevToolsProtocol::Response>
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "cc/output/compositor_frame_metadata.h" #include "cc/output/compositor_frame_metadata.h"
#include "content/browser/devtools/devtools_protocol.h" #include "content/browser/devtools/devtools_protocol.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/browser/render_widget_host.h"
#include "third_party/skia/include/core/SkBitmap.h"
class SkBitmap; class SkBitmap;
...@@ -21,6 +23,10 @@ namespace IPC { ...@@ -21,6 +23,10 @@ namespace IPC {
class Message; class Message;
} }
namespace blink {
class WebMouseEvent;
}
namespace content { namespace content {
class DevToolsTracingHandler; class DevToolsTracingHandler;
...@@ -79,6 +85,8 @@ class CONTENT_EXPORT RendererOverridesHandler ...@@ -79,6 +85,8 @@ class CONTENT_EXPORT RendererOverridesHandler
scoped_refptr<DevToolsProtocol::Command> command); scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> PageQueryUsageAndQuota( scoped_refptr<DevToolsProtocol::Response> PageQueryUsageAndQuota(
scoped_refptr<DevToolsProtocol::Command>); scoped_refptr<DevToolsProtocol::Command>);
scoped_refptr<DevToolsProtocol::Response> PageSetColorPickerEnabled(
scoped_refptr<DevToolsProtocol::Command>);
void ScreenshotCaptured( void ScreenshotCaptured(
scoped_refptr<DevToolsProtocol::Command> command, scoped_refptr<DevToolsProtocol::Command> command,
...@@ -97,6 +105,10 @@ class CONTENT_EXPORT RendererOverridesHandler ...@@ -97,6 +105,10 @@ class CONTENT_EXPORT RendererOverridesHandler
scoped_ptr<base::DictionaryValue> response_data); scoped_ptr<base::DictionaryValue> response_data);
void NotifyScreencastVisibility(bool visible); void NotifyScreencastVisibility(bool visible);
void SetColorPickerEnabled(bool enabled);
void UpdateColorPickerFrame();
void ColorPickerFrameUpdated(bool succeeded, const SkBitmap& bitmap);
bool HandleMouseEvent(const blink::WebMouseEvent& event);
// Input domain. // Input domain.
scoped_refptr<DevToolsProtocol::Response> InputEmulateTouchFromMouseEvent( scoped_refptr<DevToolsProtocol::Response> InputEmulateTouchFromMouseEvent(
...@@ -108,6 +120,9 @@ class CONTENT_EXPORT RendererOverridesHandler ...@@ -108,6 +120,9 @@ class CONTENT_EXPORT RendererOverridesHandler
cc::CompositorFrameMetadata last_compositor_frame_metadata_; cc::CompositorFrameMetadata last_compositor_frame_metadata_;
base::TimeTicks last_frame_time_; base::TimeTicks last_frame_time_;
int capture_retry_count_; int capture_retry_count_;
bool color_picker_enabled_;
SkBitmap color_picker_frame_;
RenderWidgetHost::MouseEventCallback mouse_event_callback_;
base::WeakPtrFactory<RendererOverridesHandler> weak_factory_; base::WeakPtrFactory<RendererOverridesHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RendererOverridesHandler); DISALLOW_COPY_AND_ASSIGN(RendererOverridesHandler);
}; };
......
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