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

Side by Side Diff: ui/snapshot/snapshot_aura.cc

Issue 137143005: Removes the rotation and scaling in SnapshotAura. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | ui/snapshot/snapshot_aura_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/snapshot/snapshot.h" 5 #include "ui/snapshot/snapshot.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
(...skipping 22 matching lines...) Expand all
33 namespace ui { 33 namespace ui {
34 34
35 namespace { 35 namespace {
36 36
37 void OnFrameScalingFinished( 37 void OnFrameScalingFinished(
38 const GrabWindowSnapshotAsyncCallback& callback, 38 const GrabWindowSnapshotAsyncCallback& callback,
39 const SkBitmap& scaled_bitmap) { 39 const SkBitmap& scaled_bitmap) {
40 callback.Run(gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(scaled_bitmap))); 40 callback.Run(gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(scaled_bitmap)));
41 } 41 }
42 42
43 void RotateBitmap(SkBitmap* bitmap, gfx::Display::Rotation rotation) { 43 SkBitmap ScaleBitmap(const SkBitmap& input_bitmap,
44 switch (rotation) { 44 gfx::Size target_size) {
sky 2014/01/24 00:44:43 const gfx::Size&
Jun Mukai 2014/01/24 01:16:11 Done.
45 case gfx::Display::ROTATE_0: 45 return skia::ImageOperations::Resize(
46 break; 46 input_bitmap,
47 case gfx::Display::ROTATE_90: 47 skia::ImageOperations::RESIZE_GOOD,
48 *bitmap = SkBitmapOperations::Rotate(*bitmap, 48 target_size.width(),
49 SkBitmapOperations::ROTATION_270_CW); 49 target_size.height(),
50 break; 50 static_cast<SkBitmap::Allocator*>(NULL));
51 case gfx::Display::ROTATE_180:
52 *bitmap = SkBitmapOperations::Rotate(*bitmap,
53 SkBitmapOperations::ROTATION_180_CW);
54 break;
55 case gfx::Display::ROTATE_270:
56 *bitmap = SkBitmapOperations::Rotate(*bitmap,
57 SkBitmapOperations::ROTATION_90_CW);
58 break;
59 }
60 } 51 }
61 52
62 SkBitmap ScaleAndRotateBitmap(const SkBitmap& input_bitmap, 53 scoped_refptr<base::RefCountedBytes> EncodeBitmap(const SkBitmap& bitmap) {
63 gfx::Size target_size_pre_rotation,
64 gfx::Display::Rotation rotation) {
65 SkBitmap bitmap;
66 bitmap =
67 skia::ImageOperations::Resize(input_bitmap,
68 skia::ImageOperations::RESIZE_GOOD,
69 target_size_pre_rotation.width(),
70 target_size_pre_rotation.height(),
71 static_cast<SkBitmap::Allocator*>(NULL));
72 RotateBitmap(&bitmap, rotation);
73 return bitmap;
74 }
75
76 scoped_refptr<base::RefCountedBytes> ScaleRotateAndEncodeBitmap(
77 const SkBitmap& input_bitmap,
78 gfx::Size target_size_pre_rotation,
79 gfx::Display::Rotation rotation) {
80 SkBitmap bitmap =
81 ScaleAndRotateBitmap(input_bitmap, target_size_pre_rotation, rotation);
82 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 54 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
83 unsigned char* pixels = 55 unsigned char* pixels =
84 reinterpret_cast<unsigned char*>(bitmap.pixelRef()->pixels()); 56 reinterpret_cast<unsigned char*>(bitmap.pixelRef()->pixels());
85 if (!gfx::PNGCodec::Encode(pixels, 57 if (!gfx::PNGCodec::Encode(pixels,
86 gfx::PNGCodec::FORMAT_BGRA, 58 gfx::PNGCodec::FORMAT_BGRA,
87 gfx::Size(bitmap.width(), bitmap.height()), 59 gfx::Size(bitmap.width(), bitmap.height()),
88 base::checked_cast<int>(bitmap.rowBytes()), 60 base::checked_cast<int>(bitmap.rowBytes()),
89 true, 61 true,
90 std::vector<gfx::PNGCodec::Comment>(), 62 std::vector<gfx::PNGCodec::Comment>(),
91 &png_data->data())) { 63 &png_data->data())) {
92 return scoped_refptr<base::RefCountedBytes>(); 64 return scoped_refptr<base::RefCountedBytes>();
93 } 65 }
94 return png_data; 66 return png_data;
95 } 67 }
96 68
97 void ScaleAndRotateCopyOutputResult( 69 void ScaleCopyOutputResult(
98 const GrabWindowSnapshotAsyncCallback& callback, 70 const GrabWindowSnapshotAsyncCallback& callback,
99 const gfx::Size& target_size, 71 const gfx::Size& target_size,
100 gfx::Display::Rotation rotation,
101 scoped_refptr<base::TaskRunner> background_task_runner, 72 scoped_refptr<base::TaskRunner> background_task_runner,
102 scoped_ptr<cc::CopyOutputResult> result) { 73 scoped_ptr<cc::CopyOutputResult> result) {
103 if (result->IsEmpty()) { 74 if (result->IsEmpty()) {
104 callback.Run(gfx::Image()); 75 callback.Run(gfx::Image());
105 return; 76 return;
106 } 77 }
107 78
108 // TODO(sergeyu): Potentially images can be scaled on GPU before reading it 79 // TODO(sergeyu): Potentially images can be scaled on GPU before reading it
109 // from GPU. Image scaling is implemented in content::GlHelper, but it's can't 80 // from GPU. Image scaling is implemented in content::GlHelper, but it's can't
110 // be used here because it's not in content/public. Move the scaling code 81 // be used here because it's not in content/public. Move the scaling code
111 // somewhere so that it can be reused here. 82 // somewhere so that it can be reused here.
112 base::PostTaskAndReplyWithResult( 83 base::PostTaskAndReplyWithResult(
113 background_task_runner, 84 background_task_runner,
114 FROM_HERE, 85 FROM_HERE,
115 base::Bind( 86 base::Bind(ScaleBitmap, *result->TakeBitmap(), target_size),
116 ScaleAndRotateBitmap, *result->TakeBitmap(), target_size, rotation),
117 base::Bind(&OnFrameScalingFinished, callback)); 87 base::Bind(&OnFrameScalingFinished, callback));
118 } 88 }
119 89
120 void ScaleRotateAndEncodeCopyOutputResult( 90 void EncodeCopyOutputResult(
121 const GrabWindowSnapshotAsyncPNGCallback& callback, 91 const GrabWindowSnapshotAsyncPNGCallback& callback,
122 const gfx::Size& target_size,
123 gfx::Display::Rotation rotation,
124 scoped_refptr<base::TaskRunner> background_task_runner, 92 scoped_refptr<base::TaskRunner> background_task_runner,
125 scoped_ptr<cc::CopyOutputResult> result) { 93 scoped_ptr<cc::CopyOutputResult> result) {
126 if (result->IsEmpty()) { 94 if (result->IsEmpty()) {
127 callback.Run(scoped_refptr<base::RefCountedBytes>()); 95 callback.Run(scoped_refptr<base::RefCountedBytes>());
128 return; 96 return;
129 } 97 }
130 98
131 // TODO(sergeyu): Potentially images can be scaled on GPU before reading it 99 // TODO(sergeyu): Potentially images can be scaled on GPU before reading it
132 // from GPU. Image scaling is implemented in content::GlHelper, but it's can't 100 // from GPU. Image scaling is implemented in content::GlHelper, but it's can't
133 // be used here because it's not in content/public. Move the scaling code 101 // be used here because it's not in content/public. Move the scaling code
134 // somewhere so that it can be reused here. 102 // somewhere so that it can be reused here.
135 base::PostTaskAndReplyWithResult(background_task_runner, 103 base::PostTaskAndReplyWithResult(background_task_runner,
136 FROM_HERE, 104 FROM_HERE,
137 base::Bind(ScaleRotateAndEncodeBitmap, 105 base::Bind(EncodeBitmap,
138 *result->TakeBitmap(), 106 *result->TakeBitmap()),
139 target_size,
140 rotation),
141 callback); 107 callback);
142 } 108 }
143 109
144 gfx::Rect GetTargetBoundsFromWindow(gfx::NativeWindow window,
145 gfx::Rect snapshot_bounds) {
146 gfx::RectF read_pixels_bounds = snapshot_bounds;
147
148 // We must take into account the window's position on the desktop.
149 read_pixels_bounds.Offset(
150 window->GetBoundsInRootWindow().origin().OffsetFromOrigin());
151 aura::WindowEventDispatcher* dispatcher = window->GetDispatcher();
152 if (dispatcher)
153 dispatcher->host()->GetRootTransform().TransformRect(&read_pixels_bounds);
154
155 gfx::Rect read_pixels_bounds_in_pixel =
156 gfx::ToEnclosingRect(read_pixels_bounds);
157
158 // Sometimes (i.e. when using Aero on Windows) the compositor's size is
159 // smaller than the window bounds. So trim appropriately.
160 ui::Compositor* compositor = window->layer()->GetCompositor();
161 read_pixels_bounds_in_pixel.Intersect(gfx::Rect(compositor->size()));
162
163 DCHECK_LE(0, read_pixels_bounds.x());
164 DCHECK_LE(0, read_pixels_bounds.y());
165
166 return read_pixels_bounds_in_pixel;
167 }
168
169 } // namespace 110 } // namespace
170 111
171 bool GrabViewSnapshot(gfx::NativeView view, 112 bool GrabViewSnapshot(gfx::NativeView view,
172 std::vector<unsigned char>* png_representation, 113 std::vector<unsigned char>* png_representation,
173 const gfx::Rect& snapshot_bounds) { 114 const gfx::Rect& snapshot_bounds) {
174 return GrabWindowSnapshot(view, png_representation, snapshot_bounds); 115 return GrabWindowSnapshot(view, png_representation, snapshot_bounds);
175 } 116 }
176 117
177 bool GrabWindowSnapshot(gfx::NativeWindow window, 118 bool GrabWindowSnapshot(gfx::NativeWindow window,
178 std::vector<unsigned char>* png_representation, 119 std::vector<unsigned char>* png_representation,
(...skipping 11 matching lines...) Expand all
190 request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect)); 131 request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect));
191 window->layer()->RequestCopyOfOutput(request.Pass()); 132 window->layer()->RequestCopyOfOutput(request.Pass());
192 } 133 }
193 134
194 void GrabWindowSnapshotAndScaleAsync( 135 void GrabWindowSnapshotAndScaleAsync(
195 gfx::NativeWindow window, 136 gfx::NativeWindow window,
196 const gfx::Rect& source_rect, 137 const gfx::Rect& source_rect,
197 const gfx::Size& target_size, 138 const gfx::Size& target_size,
198 scoped_refptr<base::TaskRunner> background_task_runner, 139 scoped_refptr<base::TaskRunner> background_task_runner,
199 const GrabWindowSnapshotAsyncCallback& callback) { 140 const GrabWindowSnapshotAsyncCallback& callback) {
200 // target_size is post-rotation, and so logically this is a rotate and then
201 // scale operation. However, it will usually be more efficient to scale first
202 // (given that this is mostly used for thumbnails) and then rotate.
203 gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window)
204 ->GetDisplayNearestWindow(window)
205 .rotation();
206 gfx::Size rotated_target_size;
207 switch (rotation) {
208 case gfx::Display::ROTATE_0:
209 case gfx::Display::ROTATE_180:
210 rotated_target_size = target_size;
211 break;
212 case gfx::Display::ROTATE_90:
213 case gfx::Display::ROTATE_270:
214 rotated_target_size =
215 gfx::Size(target_size.height(), target_size.width());
216 break;
217 };
218
219 MakeAsyncCopyRequest(window, 141 MakeAsyncCopyRequest(window,
220 source_rect, 142 source_rect,
221 base::Bind(&ScaleAndRotateCopyOutputResult, 143 base::Bind(&ScaleCopyOutputResult,
222 callback, 144 callback,
223 rotated_target_size, 145 target_size,
224 rotation,
225 background_task_runner)); 146 background_task_runner));
226 } 147 }
227 148
228 void GrabWindowSnapshotAsync( 149 void GrabWindowSnapshotAsync(
229 gfx::NativeWindow window, 150 gfx::NativeWindow window,
230 const gfx::Rect& source_rect, 151 const gfx::Rect& source_rect,
231 scoped_refptr<base::TaskRunner> background_task_runner, 152 scoped_refptr<base::TaskRunner> background_task_runner,
232 const GrabWindowSnapshotAsyncPNGCallback& callback) { 153 const GrabWindowSnapshotAsyncPNGCallback& callback) {
233 gfx::Size target_size = GetTargetBoundsFromWindow(window, source_rect).size();
234 gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window)
235 ->GetDisplayNearestWindow(window)
236 .rotation();
237 MakeAsyncCopyRequest(window, 154 MakeAsyncCopyRequest(window,
238 source_rect, 155 source_rect,
239 base::Bind(&ScaleRotateAndEncodeCopyOutputResult, 156 base::Bind(&EncodeCopyOutputResult,
240 callback, 157 callback,
241 target_size,
242 rotation,
243 background_task_runner)); 158 background_task_runner));
244 } 159 }
245 160
246 void GrabViewSnapshotAsync( 161 void GrabViewSnapshotAsync(
247 gfx::NativeView view, 162 gfx::NativeView view,
248 const gfx::Rect& source_rect, 163 const gfx::Rect& source_rect,
249 scoped_refptr<base::TaskRunner> background_task_runner, 164 scoped_refptr<base::TaskRunner> background_task_runner,
250 const GrabWindowSnapshotAsyncPNGCallback& callback) { 165 const GrabWindowSnapshotAsyncPNGCallback& callback) {
251 GrabWindowSnapshotAsync(view, source_rect, background_task_runner, callback); 166 GrabWindowSnapshotAsync(view, source_rect, background_task_runner, callback);
252 } 167 }
253 168
254 169
255 } // namespace ui 170 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | ui/snapshot/snapshot_aura_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698