Chromium Code Reviews| Index: content/browser/devtools/protocol/page_handler.cc |
| diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc |
| index f7ec85bdfcf5656d0333a85243abb6658c9d6b7d..9d2b1d7095e928a1524d51b53cf013c8927e82c6 100644 |
| --- a/content/browser/devtools/protocol/page_handler.cc |
| +++ b/content/browser/devtools/protocol/page_handler.cc |
| @@ -9,6 +9,8 @@ |
| #include "base/base64.h" |
| #include "base/bind.h" |
| #include "base/location.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/ref_counted_memory.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/utf_string_conversions.h" |
| @@ -37,6 +39,8 @@ |
| #include "ui/gfx/codec/jpeg_codec.h" |
| #include "ui/gfx/codec/png_codec.h" |
| #include "ui/gfx/geometry/size_conversions.h" |
| +#include "ui/gfx/image/image.h" |
| +#include "ui/gfx/image/image_util.h" |
| #include "ui/snapshot/snapshot.h" |
| #include "url/gurl.h" |
| @@ -52,37 +56,27 @@ static int kFrameRetryDelayMs = 100; |
| static int kCaptureRetryLimit = 2; |
| static int kMaxScreencastFramesInFlight = 2; |
| -std::string EncodeScreencastFrame(const SkBitmap& bitmap, |
| - const std::string& format, |
| - int quality) { |
| - std::vector<unsigned char> data; |
| - SkAutoLockPixels lock_image(bitmap); |
| - bool encoded; |
| +std::string EncodeImage(const gfx::Image& image, |
| + const std::string& format, |
| + int quality) { |
| + DCHECK(!image.IsEmpty()); |
| + |
| + scoped_refptr<base::RefCountedMemory> data; |
| if (format == kPng) { |
| - encoded = gfx::PNGCodec::Encode( |
| - reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), |
| - gfx::PNGCodec::FORMAT_SkBitmap, |
| - gfx::Size(bitmap.width(), bitmap.height()), |
| - bitmap.width() * bitmap.bytesPerPixel(), |
| - false, std::vector<gfx::PNGCodec::Comment>(), &data); |
| + data = image.As1xPNGBytes(); |
| } else if (format == kJpeg) { |
| - encoded = gfx::JPEGCodec::Encode( |
| - reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), |
| - gfx::JPEGCodec::FORMAT_SkBitmap, |
| - bitmap.width(), |
| - bitmap.height(), |
| - bitmap.width() * bitmap.bytesPerPixel(), |
| - quality, &data); |
| - } else { |
| - encoded = false; |
| + scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes()); |
| + if (gfx::JPEG1xEncodedDataFromImage(image, quality, &bytes->data())) |
| + data = bytes; |
| } |
| - if (!encoded) |
| + if (!data || !data->front()) |
| return std::string(); |
| std::string base_64_data; |
| base::Base64Encode( |
| - base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()), |
| + base::StringPiece(reinterpret_cast<const char*>(data->front()), |
| + data->size()), |
| &base_64_data); |
| return base_64_data; |
| @@ -285,15 +279,21 @@ Response PageHandler::NavigateToHistoryEntry(int entry_id) { |
| } |
| void PageHandler::CaptureScreenshot( |
| + Maybe<std::string> format, |
| + Maybe<int> quality, |
| std::unique_ptr<CaptureScreenshotCallback> callback) { |
| if (!host_ || !host_->GetRenderWidgetHost()) { |
| callback->sendFailure(Response::InternalError()); |
| return; |
| } |
| + std::string screenshot_format = format.fromMaybe(kPng); |
| + int screenshot_quality = quality.fromMaybe(kDefaultScreenshotQuality); |
| + |
| host_->GetRenderWidgetHost()->GetSnapshotFromBrowser( |
| - base::Bind(&PageHandler::ScreenshotCaptured, |
| - weak_factory_.GetWeakPtr(), base::Passed(std::move(callback)))); |
| + base::Bind(&PageHandler::ScreenshotCaptured, weak_factory_.GetWeakPtr(), |
| + base::Passed(std::move(callback)), screenshot_format, |
| + screenshot_quality)); |
| } |
| Response PageHandler::StartScreencast(Maybe<std::string> format, |
| @@ -519,8 +519,8 @@ void PageHandler::ScreencastFrameCaptured(cc::CompositorFrameMetadata metadata, |
| base::PostTaskWithTraitsAndReplyWithResult( |
| FROM_HERE, base::TaskTraits().WithShutdownBehavior( |
| base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), |
| - base::Bind(&EncodeScreencastFrame, bitmap, screencast_format_, |
| - screencast_quality_), |
| + base::Bind(&EncodeImage, gfx::Image::CreateFrom1xBitmap(bitmap), |
| + screencast_format_, screencast_quality_), |
| base::Bind(&PageHandler::ScreencastFrameEncoded, |
| weak_factory_.GetWeakPtr(), base::Passed(&metadata), |
| base::Time::Now())); |
| @@ -561,18 +561,26 @@ void PageHandler::ScreencastFrameEncoded(cc::CompositorFrameMetadata metadata, |
| void PageHandler::ScreenshotCaptured( |
| std::unique_ptr<CaptureScreenshotCallback> callback, |
| - const unsigned char* png_data, |
| - size_t png_size) { |
| - if (!png_data || !png_size) { |
| + const std::string& format, |
| + int quality, |
| + const gfx::Image& image) { |
| + if (image.IsEmpty()) { |
| callback->sendFailure(Response::Error("Unable to capture screenshot")); |
| return; |
| } |
| - std::string base_64_data; |
| - base::Base64Encode( |
| - base::StringPiece(reinterpret_cast<const char*>(png_data), png_size), |
| - &base_64_data); |
| - callback->sendSuccess(base_64_data); |
| + base::PostTaskWithTraitsAndReplyWithResult( |
|
pfeldman
2017/01/07 01:13:27
Why is this necessary? Weren't we doing it synchro
Eric Seckler
2017/01/09 14:52:04
Great, making it synchronous :) Previously, it was
|
| + FROM_HERE, base::TaskTraits().WithShutdownBehavior( |
| + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN), |
| + base::Bind(&EncodeImage, image, format, quality), |
| + base::Bind(&PageHandler::ScreenshotEncoded, weak_factory_.GetWeakPtr(), |
| + base::Passed(std::move(callback)))); |
| +} |
| + |
| +void PageHandler::ScreenshotEncoded( |
| + std::unique_ptr<CaptureScreenshotCallback> callback, |
| + const std::string& data) { |
| + callback->sendSuccess(data); |
| } |
| void PageHandler::OnColorPicked(int r, int g, int b, int a) { |