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

Side by Side Diff: chrome/browser/thumbnails/simple_thumbnail_crop.cc

Issue 1028393003: [Thumbnails] Specify copy size in Pixels, not DIPs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: correct rebase Created 5 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/thumbnails/simple_thumbnail_crop.h" 5 #include "chrome/browser/thumbnails/simple_thumbnail_crop.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "content/public/browser/browser_thread.h" 8 #include "content/public/browser/browser_thread.h"
9 #include "skia/ext/platform_canvas.h" 9 #include "skia/ext/platform_canvas.h"
10 #include "ui/base/layout.h"
10 #include "ui/gfx/color_utils.h" 11 #include "ui/gfx/color_utils.h"
11 #include "ui/gfx/geometry/size_conversions.h" 12 #include "ui/gfx/geometry/size_conversions.h"
12 #include "ui/gfx/image/image_skia.h" 13 #include "ui/gfx/image/image_skia.h"
13 #include "ui/gfx/screen.h" 14 #include "ui/gfx/screen.h"
14 #include "ui/gfx/scrollbar_size.h" 15 #include "ui/gfx/scrollbar_size.h"
15 #include "ui/gfx/skbitmap_operations.h" 16 #include "ui/gfx/skbitmap_operations.h"
16 17
17 namespace { 18 namespace {
18 static const char kThumbnailHistogramName[] = "Thumbnail.ComputeMS"; 19 static const char kThumbnailHistogramName[] = "Thumbnail.ComputeMS";
19 } 20 }
20 21
21 namespace thumbnails { 22 namespace thumbnails {
22 23
23 SimpleThumbnailCrop::SimpleThumbnailCrop(const gfx::Size& target_size) 24 SimpleThumbnailCrop::SimpleThumbnailCrop(const gfx::Size& target_size)
24 : target_size_(target_size) { 25 : target_size_(target_size) {
25 DCHECK(!target_size.IsEmpty()); 26 DCHECK(!target_size.IsEmpty());
26 } 27 }
27 28
28 ClipResult SimpleThumbnailCrop::GetCanvasCopyInfo( 29 ClipResult SimpleThumbnailCrop::GetCanvasCopyInfo(const gfx::Size& source_size,
29 const gfx::Size& source_size, 30 ui::ScaleFactor scale_factor,
30 ui::ScaleFactor scale_factor, 31 gfx::Rect* clipping_rect,
31 gfx::Rect* clipping_rect, 32 gfx::Size* copy_size) const {
32 gfx::Size* target_size) const {
33 DCHECK(!source_size.IsEmpty()); 33 DCHECK(!source_size.IsEmpty());
34 ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED; 34 ClipResult clip_result = thumbnails::CLIP_RESULT_NOT_CLIPPED;
35 *clipping_rect = GetClippingRect(source_size, target_size_, &clip_result); 35 *clipping_rect = GetClippingRect(source_size, target_size_, &clip_result);
36 *target_size = GetCopySizeForThumbnail(scale_factor, target_size_); 36 *copy_size = GetCopySizeForThumbnail(scale_factor, target_size_);
37 return clip_result; 37 return clip_result;
38 } 38 }
39 39
40 void SimpleThumbnailCrop::ProcessBitmap( 40 void SimpleThumbnailCrop::ProcessBitmap(
41 scoped_refptr<ThumbnailingContext> context, 41 scoped_refptr<ThumbnailingContext> context,
42 const ConsumerCallback& callback, 42 const ConsumerCallback& callback,
43 const SkBitmap& bitmap) { 43 const SkBitmap& bitmap) {
44 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 44 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
45 if (bitmap.isNull() || bitmap.empty()) 45 if (bitmap.isNull() || bitmap.empty())
46 return; 46 return;
(...skipping 20 matching lines...) Expand all
67 GetClippingRect(gfx::Size(bitmap.width(), bitmap.height()), 67 GetClippingRect(gfx::Size(bitmap.width(), bitmap.height()),
68 gfx::Size(desired_width, desired_height), 68 gfx::Size(desired_width, desired_height),
69 clip_result); 69 clip_result);
70 SkIRect src_rect = { clipping_rect.x(), clipping_rect.y(), 70 SkIRect src_rect = { clipping_rect.x(), clipping_rect.y(),
71 clipping_rect.right(), clipping_rect.bottom() }; 71 clipping_rect.right(), clipping_rect.bottom() };
72 SkBitmap clipped_bitmap; 72 SkBitmap clipped_bitmap;
73 bitmap.extractSubset(&clipped_bitmap, src_rect); 73 bitmap.extractSubset(&clipped_bitmap, src_rect);
74 return clipped_bitmap; 74 return clipped_bitmap;
75 } 75 }
76 76
77 // Returns the size used by RenderWidgetHost::CopyFromBackingStore. 77 // RenderWidgetHost::CopyFromBackingStore can be costly especially when it is
78 // 78 // necessary to read back the web contents image data from GPU. As the cost is
79 // The size is calculated in such a way that the copied size in pixel becomes 79 // roughly proportional to the number of the copied pixels, the size of the
80 // equal to (f * kThumbnailWidth, f * kThumbnailHeight), where f is the scale 80 // copied pixels should be as small as possible.
81 // of ui::SCALE_FACTOR_200P. Since RenderWidgetHost::CopyFromBackingStore takes
82 // the size in DIP, we need to adjust the size based on |view|'s device scale
83 // factor in order to copy the pixels with the size above.
84 //
85 // The copied size was chosen for the following reasons.
86 //
87 // 1. When the scale factor of the primary monitor is ui::SCALE_FACTOR_200P, the
88 // generated thumbnail size is (f * kThumbnailWidth, f * kThumbnailHeight).
89 // In order to avoid degrading the image quality by magnification, the size
90 // of the copied pixels should be equal to or larger than this thumbnail size.
91 //
92 // 2. RenderWidgetHost::CopyFromBackingStore can be costly especially when
93 // it is necessary to read back the web contents image data from GPU. As the
94 // cost is roughly propotional to the number of the copied pixels, the size of
95 // the copied pixels should be as small as possible.
96 //
97 // When the scale factor of the primary monitor is ui::SCALE_FACTOR_100P,
98 // we still copy the pixels with the same size as ui::SCALE_FACTOR_200P (2.0f)
99 // because the resampling method used in RenderWidgetHost::CopyFromBackingStore
100 // is not good enough for the resampled image to be used directly for the
101 // thumbnail (http://crbug.com/141235). We assume this is not an issue in case o f
102 // ui::SCALE_FACTOR_200P because the high resolution thumbnail on high density
103 // display alleviates the aliasing.
104 // TODO(mazda): Copy the pixels with the smaller size in the case of
105 // ui::SCALE_FACTOR_100P once the resampling method has been improved.
106 // static 81 // static
107 gfx::Size SimpleThumbnailCrop::GetCopySizeForThumbnail( 82 gfx::Size SimpleThumbnailCrop::GetCopySizeForThumbnail(
108 ui::ScaleFactor scale_factor, 83 ui::ScaleFactor scale_factor,
109 const gfx::Size& thumbnail_size) { 84 const gfx::Size& thumbnail_size) {
110 gfx::Size copy_size(thumbnail_size); 85 // The copy size returned is the pixel equivalent of |thumbnail_size|, which
111 switch (scale_factor) { 86 // is in DIPs.
112 case ui::SCALE_FACTOR_100P: 87 if (scale_factor == ui::SCALE_FACTOR_100P) {
113 copy_size = gfx::ToFlooredSize(gfx::ScaleSize(copy_size, 2.0f)); 88 // In the case of 1x devices, we get a thumbnail twice as big and reduce
114 break; 89 // it at serve time to improve quality.
115 case ui::SCALE_FACTOR_200P: 90 scale_factor = ui::SCALE_FACTOR_200P;
116 // Use the size as-is.
117 break;
118 default:
119 DLOG(WARNING) << "Unsupported scale factor. Use the same copy size as "
120 << "ui::SCALE_FACTOR_100P";
121 copy_size = gfx::ToFlooredSize(gfx::ScaleSize(
122 copy_size, gfx::ImageSkia::GetMaxSupportedScale()));
123 break;
124 } 91 }
125 return copy_size; 92 float scale = GetScaleForScaleFactor(scale_factor);
93 return gfx::ToFlooredSize(gfx::ScaleSize(thumbnail_size, scale));
126 } 94 }
127 95
128 gfx::Rect SimpleThumbnailCrop::GetClippingRect(const gfx::Size& source_size, 96 gfx::Rect SimpleThumbnailCrop::GetClippingRect(const gfx::Size& source_size,
129 const gfx::Size& desired_size, 97 const gfx::Size& desired_size,
130 ClipResult* clip_result) { 98 ClipResult* clip_result) {
131 DCHECK(clip_result); 99 DCHECK(clip_result);
132 100
133 float desired_aspect = 101 float desired_aspect =
134 static_cast<float>(desired_size.width()) / desired_size.height(); 102 static_cast<float>(desired_size.width()) / desired_size.height();
135 103
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 clipped_bitmap.height() == result.height()) 194 clipped_bitmap.height() == result.height())
227 clipped_bitmap.copyTo(&result, kN32_SkColorType); 195 clipped_bitmap.copyTo(&result, kN32_SkColorType);
228 #endif 196 #endif
229 197
230 LOCAL_HISTOGRAM_TIMES(kThumbnailHistogramName, 198 LOCAL_HISTOGRAM_TIMES(kThumbnailHistogramName,
231 base::TimeTicks::Now() - begin_compute_thumbnail); 199 base::TimeTicks::Now() - begin_compute_thumbnail);
232 return result; 200 return result;
233 } 201 }
234 202
235 } // namespace thumbnails 203 } // namespace thumbnails
OLDNEW
« no previous file with comments | « chrome/browser/thumbnails/simple_thumbnail_crop.h ('k') | chrome/browser/thumbnails/simple_thumbnail_crop_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698