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

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

Issue 10831207: Make ThumbnailGenerator support high DPI. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add TODO comment 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 | « no previous file | 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 a338c5e089ea42cb00599286412440a390c7f43e..ab0d5f32358714e27951e0479291a16bfb2f6476 100644
--- a/chrome/browser/tab_contents/thumbnail_generator.cc
+++ b/chrome/browser/tab_contents/thumbnail_generator.cc
@@ -31,6 +31,7 @@
#include "ui/base/layout.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/rect.h"
+#include "ui/gfx/screen.h"
#include "ui/gfx/scrollbar_size.h"
#include "ui/gfx/skbitmap_operations.h"
@@ -65,32 +66,70 @@ using content::WebContents;
namespace {
+// The thumbnail size in DIP.
static const int kThumbnailWidth = 212;
static const int kThumbnailHeight = 132;
-// This factor determines the number of pixels to be copied by
-// RenderWidgetHost::CopyFromBackingStore for generating thumbnail.
-// Smaller scale is good for performance, but too small scale causes aliasing
-// because the resampling method is not good enough to retain the image quality.
-// TODO(mazda): the Improve resampling method and use a smaller scale
-// (http://crbug.com/118571).
-static const double kThumbnailCopyScale = 2.0;
-
static const char kThumbnailHistogramName[] = "Thumbnail.ComputeMS";
-// Calculates the size used by RenderWidgetHost::CopyFromBackingStore.
-// The result is computed as the minimum size that satisfies the following
-// conditions.
-// result.width : result.height == view_size.width : view_size.height
-// result.width >= kThumbnailCopyScale * desired_size.width
-// result.height >= kThumbnailCopyScale * desired_size.height
-gfx::Size GetCopySizeForThumbnail(const gfx::Size& view_size,
- const gfx::Size& desired_size) {
- const double scale = kThumbnailCopyScale *
- std::max(static_cast<double>(desired_size.width()) / view_size.width(),
- static_cast<double>(desired_size.height()) / view_size.height());
- return gfx::Size(static_cast<int>(scale * view_size.width()),
- static_cast<int>(scale * view_size.height()));
+// Returns the size used by RenderWidgetHost::CopyFromBackingStore.
+//
+// The size is calculated in such a way that the copied size in pixel becomes
+// equal to (f * kThumbnailWidth, f * kThumbnailHeight), where f is the scale
+// of ui::SCALE_FACTOR_200P. Since RenderWidgetHost::CopyFromBackingStore takes
+// the size in DIP, we need to adjust the size based on |view|'s device scale
+// factor in order to copy the pixels with the size above.
+//
+// The copied size was chosen for the following reasons.
+//
+// 1. When the scale factor of the primary monitor is ui::SCALE_FACTOR_200P, the
+// generated thumbnail size is (f * kThumbnailWidth, f * kThumbnailHeight).
+// In order to avoid degrading the image quality by magnification, the size
+// of the copied pixels should be equal to or larger than this thumbnail size.
+//
+// 2. RenderWidgetHost::CopyFromBackingStore can be costly especially when
+// it is necessary to read back the web contents image data from GPU. As the
+// cost is roughly propotional to the number of the copied pixels, the size of
+// the copied pixels should be as small as possible.
+//
+// When the scale factor of the primary monitor is ui::SCALE_FACTOR_100P,
+// we still copy the pixels with the same size as ui::SCALE_FACTOR_200P because
+// the resampling method used in RenderWidgetHost::CopyFromBackingStore is not
+// good enough for the resampled image to be used directly for the thumbnail
+// (http://crbug.com/141235). We assume this is not an issue in case of
+// ui::SCALE_FACTOR_200P because the high resolution thumbnail on high density
+// display alleviates the aliasing.
+// TODO(mazda): Copy the pixels with the smaller size in the case of
+// ui::SCALE_FACTOR_100P once the resampling method has been improved.
+gfx::Size GetCopySizeForThumbnail(content::RenderWidgetHostView* view) {
+ gfx::Size copy_size(kThumbnailWidth, kThumbnailHeight);
+ ui::ScaleFactor scale_factor =
+ ui::GetScaleFactorForNativeView(view->GetNativeView());
+ switch (scale_factor) {
+ case ui::SCALE_FACTOR_100P:
+ copy_size =
+ copy_size.Scale(ui::GetScaleFactorScale(ui::SCALE_FACTOR_200P));
+ break;
+ case ui::SCALE_FACTOR_200P:
+ // Use the size as-is.
+ break;
+ default:
+ DLOG(WARNING) << "Unsupported scale factor. Use the same copy size as "
+ << "ui::SCALE_FACTOR_100P";
+ copy_size =
+ copy_size.Scale(ui::GetScaleFactorScale(ui::SCALE_FACTOR_200P));
+ break;
+ }
+ return copy_size;
+}
+
+// Returns the size of the thumbnail stored in the database in pixel.
+gfx::Size GetThumbnailSizeInPixel() {
+ gfx::Size thumbnail_size(kThumbnailWidth, kThumbnailHeight);
+ // Determine the resolution of the thumbnail based on the primary monitor.
+ // TODO(oshima): Use device's default scale factor.
+ gfx::Display primary_display = gfx::Screen::GetPrimaryDisplay();
+ return thumbnail_size.Scale(primary_display.device_scale_factor());
}
// Returns the clipping rectangle that is used for creating a thumbnail with
@@ -142,8 +181,7 @@ gfx::Rect GetClippingRect(const gfx::Size& source_size,
// store. The returned bitmap will be isNull if there was an error creating it.
SkBitmap CreateThumbnail(
const SkBitmap& bitmap,
- int desired_width,
- int desired_height,
+ const gfx::Size& desired_size,
ThumbnailGenerator::ClipResult* clip_result) {
base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now();
@@ -160,7 +198,7 @@ SkBitmap CreateThumbnail(
bitmap.extractSubset(&bmp, scrollbarless_rect);
clipped_bitmap = ThumbnailGenerator::GetClippedBitmap(
- bmp, desired_width, desired_height, clip_result);
+ bmp, desired_size.width(), desired_size.height(), clip_result);
} else {
clipped_bitmap = bitmap;
}
@@ -168,7 +206,7 @@ SkBitmap CreateThumbnail(
// 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.
SkBitmap result = SkBitmapOperations::DownsampleByTwoUntilSize(
- clipped_bitmap, desired_width, desired_height);
+ clipped_bitmap, desired_size.width(), desired_size.height());
#if !defined(USE_AURA)
// This is a bit subtle. SkBitmaps are refcounted, but the magic
// ones in PlatformCanvas can't be assigned to SkBitmap with proper
@@ -523,8 +561,7 @@ void ThumbnailGenerator::AsyncUpdateThumbnail(
copy_rect = GetClippingRect(copy_rect.size(),
gfx::Size(kThumbnailWidth, kThumbnailHeight),
&clip_result);
- gfx::Size copy_size =
- gfx::Size(kThumbnailWidth, kThumbnailHeight).Scale(kThumbnailCopyScale);
+ gfx::Size copy_size = GetCopySizeForThumbnail(view);
skia::PlatformCanvas* temp_canvas = new skia::PlatformCanvas;
render_widget_host->CopyFromBackingStore(
copy_rect,
@@ -546,8 +583,7 @@ void ThumbnailGenerator::UpdateThumbnailWithBitmap(
return;
SkBitmap thumbnail = CreateThumbnail(bitmap,
- kThumbnailWidth,
- kThumbnailHeight,
+ GetThumbnailSizeInPixel(),
&clip_result);
UpdateThumbnail(web_contents, thumbnail, clip_result);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698