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

Unified Diff: chrome/browser/tab_contents/thumbnail_generator.cc

Issue 10831063: Clip the bitmap for creating the thumbnail on GPU when accelerated compositing is active. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/tab_contents/thumbnail_generator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/tab_contents/thumbnail_generator.cc
diff --git a/chrome/browser/tab_contents/thumbnail_generator.cc b/chrome/browser/tab_contents/thumbnail_generator.cc
index f5cfb5790b4a28ef32796fc61f404515a21408da..dab34e52167198d0c0386f76557b0543aa462d88 100644
--- a/chrome/browser/tab_contents/thumbnail_generator.cc
+++ b/chrome/browser/tab_contents/thumbnail_generator.cc
@@ -30,6 +30,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/rect.h"
+#include "ui/gfx/scrollbar_size.h"
#include "ui/gfx/skbitmap_operations.h"
#if defined(OS_WIN)
@@ -91,26 +92,77 @@ gfx::Size GetCopySizeForThumbnail(const gfx::Size& view_size,
static_cast<int>(scale * view_size.height()));
}
+// Returns the clipping rectangle that is used for creating a thumbnail with
+// the size of |desired_size| from the bitmap with the size of |source_size|.
+// The type of clipping that needs to be done is assigned to |clip_result|.
+gfx::Rect GetClippingRect(const gfx::Size& source_size,
+ const gfx::Size& desired_size,
+ ThumbnailGenerator::ClipResult* clip_result) {
+ DCHECK(clip_result);
+
+ float desired_aspect =
+ static_cast<float>(desired_size.width()) / desired_size.height();
+
+ // Get the clipping rect so that we can preserve the aspect ratio while
+ // filling the destination.
+ gfx::Rect clipping_rect;
+ if (source_size.width() < desired_size.width() ||
+ source_size.height() < desired_size.height()) {
+ // Source image is smaller: we clip the part of source image within the
+ // dest rect, and then stretch it to fill the dest rect. We don't respect
+ // the aspect ratio in this case.
+ clipping_rect = gfx::Rect(desired_size);
+ *clip_result = ThumbnailGenerator::kSourceIsSmaller;
+ } else {
+ float src_aspect =
+ static_cast<float>(source_size.width()) / source_size.height();
+ if (src_aspect > desired_aspect) {
+ // Wider than tall, clip horizontally: we center the smaller
+ // thumbnail in the wider screen.
+ int new_width = static_cast<int>(source_size.height() * desired_aspect);
+ int x_offset = (source_size.width() - new_width) / 2;
+ clipping_rect.SetRect(x_offset, 0, new_width, source_size.height());
+ *clip_result = (src_aspect >= ThumbnailScore::kTooWideAspectRatio) ?
+ ThumbnailGenerator::kTooWiderThanTall :
+ ThumbnailGenerator::kWiderThanTall;
+ } else if (src_aspect < desired_aspect) {
+ clipping_rect =
+ gfx::Rect(source_size.width(), source_size.width() / desired_aspect);
+ *clip_result = ThumbnailGenerator::kTallerThanWide;
+ } else {
+ clipping_rect = gfx::Rect(source_size);
+ *clip_result = ThumbnailGenerator::kNotClipped;
+ }
+ }
+ return clipping_rect;
+}
+
// Creates a downsampled thumbnail from the given bitmap.
// store. The returned bitmap will be isNull if there was an error creating it.
SkBitmap CreateThumbnail(
- const SkBitmap& bmp_with_scrollbars,
+ const SkBitmap& bitmap,
int desired_width,
int desired_height,
ThumbnailGenerator::ClipResult* clip_result) {
base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now();
- // Clip the edgemost 15 pixels as that will commonly hold a scrollbar, which
- // looks bad in thumbnails.
- SkIRect scrollbarless_rect =
- { 0, 0,
- std::max(1, bmp_with_scrollbars.width() - 15),
- std::max(1, bmp_with_scrollbars.height() - 15) };
- SkBitmap bmp;
- bmp_with_scrollbars.extractSubset(&bmp, scrollbarless_rect);
-
- SkBitmap clipped_bitmap = ThumbnailGenerator::GetClippedBitmap(
- bmp, desired_width, desired_height, clip_result);
+ SkBitmap clipped_bitmap;
+ if (*clip_result == ThumbnailGenerator::kUnprocessed) {
+ // Clip the pixels that will commonly hold a scrollbar, which looks bad in
+ // thumbnails.
+ int scrollbar_size = gfx::scrollbar_size();
+ SkIRect scrollbarless_rect =
+ { 0, 0,
+ std::max(1, bitmap.width() - scrollbar_size),
+ std::max(1, bitmap.height() - scrollbar_size) };
+ SkBitmap bmp;
+ bitmap.extractSubset(&bmp, scrollbarless_rect);
+
+ clipped_bitmap = ThumbnailGenerator::GetClippedBitmap(
+ bmp, desired_width, desired_height, clip_result);
+ } else {
+ clipped_bitmap = bitmap;
+ }
// Need to resize it to the size we want, so downsample until it's
// close, and let the caller make it the exact size if desired.
@@ -376,49 +428,12 @@ SkBitmap ThumbnailGenerator::GetClippedBitmap(const SkBitmap& bitmap,
int desired_width,
int desired_height,
ClipResult* clip_result) {
- const SkRect dest_rect = { 0, 0,
- SkIntToScalar(desired_width),
- SkIntToScalar(desired_height) };
- const float dest_aspect = dest_rect.width() / dest_rect.height();
-
- // Get the src rect so that we can preserve the aspect ratio while filling
- // the destination.
- SkIRect src_rect;
- if (bitmap.width() < dest_rect.width() ||
- bitmap.height() < dest_rect.height()) {
- // Source image is smaller: we clip the part of source image within the
- // dest rect, and then stretch it to fill the dest rect. We don't respect
- // the aspect ratio in this case.
- src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
- static_cast<S16CPU>(dest_rect.height()));
- if (clip_result)
- *clip_result = ThumbnailGenerator::kSourceIsSmaller;
- } else {
- const float src_aspect =
- static_cast<float>(bitmap.width()) / bitmap.height();
- if (src_aspect > dest_aspect) {
- // Wider than tall, clip horizontally: we center the smaller
- // thumbnail in the wider screen.
- S16CPU new_width = static_cast<S16CPU>(bitmap.height() * dest_aspect);
- S16CPU x_offset = (bitmap.width() - new_width) / 2;
- src_rect.set(x_offset, 0, new_width + x_offset, bitmap.height());
- if (clip_result) {
- *clip_result = (src_aspect >= ThumbnailScore::kTooWideAspectRatio) ?
- ThumbnailGenerator::kTooWiderThanTall :
- ThumbnailGenerator::kWiderThanTall;
- }
- } else if (src_aspect < dest_aspect) {
- src_rect.set(0, 0, bitmap.width(),
- static_cast<S16CPU>(bitmap.width() / dest_aspect));
- if (clip_result)
- *clip_result = ThumbnailGenerator::kTallerThanWide;
- } else {
- src_rect.set(0, 0, bitmap.width(), bitmap.height());
- if (clip_result)
- *clip_result = ThumbnailGenerator::kNotClipped;
- }
- }
-
+ gfx::Rect clipping_rect =
+ GetClippingRect(gfx::Size(bitmap.width(), bitmap.height()),
+ gfx::Size(desired_width, desired_height),
+ clip_result);
+ SkIRect src_rect = { clipping_rect.x(), clipping_rect.y(),
+ clipping_rect.right(), clipping_rect.bottom() };
SkBitmap clipped_bitmap;
bitmap.extractSubset(&clipped_bitmap, src_rect);
return clipped_bitmap;
@@ -443,7 +458,7 @@ void ThumbnailGenerator::UpdateThumbnailIfNecessary(
void ThumbnailGenerator::UpdateThumbnail(
WebContents* web_contents, const SkBitmap& thumbnail,
- const ThumbnailGenerator::ClipResult& clip_result) {
+ const ClipResult& clip_result) {
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
@@ -486,7 +501,8 @@ void ThumbnailGenerator::AsyncUpdateThumbnail(
AskForSnapshot(render_widget_host,
base::Bind(&ThumbnailGenerator::UpdateThumbnailWithBitmap,
weak_factory_.GetWeakPtr(),
- web_contents),
+ web_contents,
+ ThumbnailGenerator::kUnprocessed),
view_size,
view_size);
}
@@ -494,28 +510,37 @@ void ThumbnailGenerator::AsyncUpdateThumbnail(
return;
}
+ gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size());
+ // Clip the pixels that will commonly hold a scrollbar, which looks bad in
+ // thumbnails.
+ int scrollbar_size = gfx::scrollbar_size();
+ copy_rect.Inset(0, 0, scrollbar_size, scrollbar_size);
+ ClipResult clip_result = ThumbnailGenerator::kUnprocessed;
+ copy_rect = GetClippingRect(copy_rect.size(),
+ gfx::Size(kThumbnailWidth, kThumbnailHeight),
+ &clip_result);
gfx::Size copy_size =
- GetCopySizeForThumbnail(view->GetViewBounds().size(),
- gfx::Size(kThumbnailWidth, kThumbnailHeight));
+ gfx::Size(kThumbnailWidth, kThumbnailHeight).Scale(kThumbnailCopyScale);
skia::PlatformCanvas* temp_canvas = new skia::PlatformCanvas;
render_widget_host->CopyFromBackingStore(
- gfx::Rect(),
+ copy_rect,
copy_size,
base::Bind(&ThumbnailGenerator::UpdateThumbnailWithCanvas,
weak_factory_.GetWeakPtr(),
web_contents,
+ clip_result,
base::Owned(temp_canvas)),
temp_canvas);
}
void ThumbnailGenerator::UpdateThumbnailWithBitmap(
WebContents* web_contents,
+ ClipResult clip_result,
const SkBitmap& bitmap) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (bitmap.isNull() || bitmap.empty())
return;
- ClipResult clip_result;
SkBitmap thumbnail = CreateThumbnail(bitmap,
kThumbnailWidth,
kThumbnailHeight,
@@ -525,15 +550,15 @@ void ThumbnailGenerator::UpdateThumbnailWithBitmap(
void ThumbnailGenerator::UpdateThumbnailWithCanvas(
WebContents* web_contents,
+ ClipResult clip_result,
skia::PlatformCanvas* temp_canvas,
bool succeeded) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (!succeeded)
return;
- SkBitmap bmp_with_scrollbars =
- skia::GetTopDevice(*temp_canvas)->accessBitmap(false);
- UpdateThumbnailWithBitmap(web_contents, bmp_with_scrollbars);
+ SkBitmap bitmap = skia::GetTopDevice(*temp_canvas)->accessBitmap(false);
+ UpdateThumbnailWithBitmap(web_contents, clip_result, bitmap);
}
bool ThumbnailGenerator::ShouldUpdateThumbnail(Profile* profile,
« no previous file with comments | « chrome/browser/tab_contents/thumbnail_generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698