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

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

Issue 126373002: Make ChromeOS screenshots use async readback path (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix rebase error 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 | « ui/snapshot/snapshot_android.cc ('k') | 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/safe_numerics.h" 10 #include "base/safe_numerics.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 bitmap = 66 bitmap =
67 skia::ImageOperations::Resize(input_bitmap, 67 skia::ImageOperations::Resize(input_bitmap,
68 skia::ImageOperations::RESIZE_GOOD, 68 skia::ImageOperations::RESIZE_GOOD,
69 target_size_pre_rotation.width(), 69 target_size_pre_rotation.width(),
70 target_size_pre_rotation.height(), 70 target_size_pre_rotation.height(),
71 static_cast<SkBitmap::Allocator*>(NULL)); 71 static_cast<SkBitmap::Allocator*>(NULL));
72 RotateBitmap(&bitmap, rotation); 72 RotateBitmap(&bitmap, rotation);
73 return bitmap; 73 return bitmap;
74 } 74 }
75 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);
83 unsigned char* pixels =
84 reinterpret_cast<unsigned char*>(bitmap.pixelRef()->pixels());
85 if (!gfx::PNGCodec::Encode(pixels,
86 gfx::PNGCodec::FORMAT_BGRA,
87 gfx::Size(bitmap.width(), bitmap.height()),
88 base::checked_numeric_cast<int>(bitmap.rowBytes()),
89 true,
90 std::vector<gfx::PNGCodec::Comment>(),
91 &png_data->data())) {
92 return scoped_refptr<base::RefCountedBytes>();
93 }
94 return png_data;
95 }
96
76 void ScaleAndRotateCopyOutputResult( 97 void ScaleAndRotateCopyOutputResult(
77 const GrabWindowSnapshotAsyncCallback& callback, 98 const GrabWindowSnapshotAsyncCallback& callback,
78 const gfx::Size& target_size, 99 const gfx::Size& target_size,
79 gfx::Display::Rotation rotation, 100 gfx::Display::Rotation rotation,
80 scoped_refptr<base::TaskRunner> background_task_runner, 101 scoped_refptr<base::TaskRunner> background_task_runner,
81 scoped_ptr<cc::CopyOutputResult> result) { 102 scoped_ptr<cc::CopyOutputResult> result) {
82 if (result->IsEmpty()) { 103 if (result->IsEmpty()) {
83 callback.Run(gfx::Image()); 104 callback.Run(gfx::Image());
84 return; 105 return;
85 } 106 }
86 107
87 // TODO(sergeyu): Potentially images can be scaled on GPU before reading it 108 // TODO(sergeyu): Potentially images can be scaled on GPU before reading it
88 // from GPU. Image scaling is implemented in content::GlHelper, but it's can't 109 // from GPU. Image scaling is implemented in content::GlHelper, but it's can't
89 // be used here because it's not in content/public. Move the scaling code 110 // be used here because it's not in content/public. Move the scaling code
90 // somewhere so that it can be reused here. 111 // somewhere so that it can be reused here.
91 base::PostTaskAndReplyWithResult( 112 base::PostTaskAndReplyWithResult(
92 background_task_runner, 113 background_task_runner,
93 FROM_HERE, 114 FROM_HERE,
94 base::Bind( 115 base::Bind(
95 ScaleAndRotateBitmap, *result->TakeBitmap(), target_size, rotation), 116 ScaleAndRotateBitmap, *result->TakeBitmap(), target_size, rotation),
96 base::Bind(&OnFrameScalingFinished, callback)); 117 base::Bind(&OnFrameScalingFinished, callback));
97 } 118 }
98 119
120 void ScaleRotateAndEncodeCopyOutputResult(
121 const GrabWindowSnapshotAsyncPNGCallback& callback,
122 const gfx::Size& target_size,
123 gfx::Display::Rotation rotation,
124 scoped_refptr<base::TaskRunner> background_task_runner,
125 scoped_ptr<cc::CopyOutputResult> result) {
126 if (result->IsEmpty()) {
127 callback.Run(scoped_refptr<base::RefCountedBytes>());
128 return;
129 }
130
131 // 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
133 // be used here because it's not in content/public. Move the scaling code
134 // somewhere so that it can be reused here.
135 base::PostTaskAndReplyWithResult(background_task_runner,
136 FROM_HERE,
137 base::Bind(ScaleRotateAndEncodeBitmap,
138 *result->TakeBitmap(),
139 target_size,
140 rotation),
141 callback);
142 }
143
99 gfx::Rect GetTargetBoundsFromWindow(gfx::NativeWindow window, 144 gfx::Rect GetTargetBoundsFromWindow(gfx::NativeWindow window,
100 gfx::Rect snapshot_bounds) { 145 gfx::Rect snapshot_bounds) {
101 gfx::RectF read_pixels_bounds = snapshot_bounds; 146 gfx::RectF read_pixels_bounds = snapshot_bounds;
102 147
103 // We must take into account the window's position on the desktop. 148 // We must take into account the window's position on the desktop.
104 read_pixels_bounds.Offset( 149 read_pixels_bounds.Offset(
105 window->GetBoundsInRootWindow().origin().OffsetFromOrigin()); 150 window->GetBoundsInRootWindow().origin().OffsetFromOrigin());
106 aura::WindowEventDispatcher* dispatcher = window->GetDispatcher(); 151 aura::WindowEventDispatcher* dispatcher = window->GetDispatcher();
107 if (dispatcher) 152 if (dispatcher)
108 dispatcher->host()->GetRootTransform().TransformRect(&read_pixels_bounds); 153 dispatcher->host()->GetRootTransform().TransformRect(&read_pixels_bounds);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 pixels, gfx::PNGCodec::FORMAT_BGRA, 195 pixels, gfx::PNGCodec::FORMAT_BGRA,
151 gfx::Size(bitmap.width(), bitmap.height()), 196 gfx::Size(bitmap.width(), bitmap.height()),
152 base::checked_numeric_cast<int>(bitmap.rowBytes()), 197 base::checked_numeric_cast<int>(bitmap.rowBytes()),
153 true, std::vector<gfx::PNGCodec::Comment>(), 198 true, std::vector<gfx::PNGCodec::Comment>(),
154 png_representation); 199 png_representation);
155 } 200 }
156 201
157 void MakeAsyncCopyRequest( 202 void MakeAsyncCopyRequest(
158 gfx::NativeWindow window, 203 gfx::NativeWindow window,
159 const gfx::Rect& source_rect, 204 const gfx::Rect& source_rect,
160 const gfx::Size& target_size, 205 const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) {
161 scoped_refptr<base::TaskRunner> background_task_runner,
162 const GrabWindowSnapshotAsyncCallback& callback) {
163 gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window)
164 ->GetDisplayNearestWindow(window)
165 .rotation();
166 scoped_ptr<cc::CopyOutputRequest> request = 206 scoped_ptr<cc::CopyOutputRequest> request =
167 cc::CopyOutputRequest::CreateBitmapRequest( 207 cc::CopyOutputRequest::CreateBitmapRequest(callback);
168 base::Bind(&ScaleAndRotateCopyOutputResult,
169 callback,
170 target_size,
171 rotation,
172 background_task_runner));
173 request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect)); 208 request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect));
174 window->layer()->RequestCopyOfOutput(request.Pass()); 209 window->layer()->RequestCopyOfOutput(request.Pass());
175 } 210 }
176 211
177 void GrabWindowSnapshotAndScaleAsync( 212 void GrabWindowSnapshotAndScaleAsync(
178 gfx::NativeWindow window, 213 gfx::NativeWindow window,
179 const gfx::Rect& source_rect, 214 const gfx::Rect& source_rect,
180 const gfx::Size& target_size, 215 const gfx::Size& target_size,
181 scoped_refptr<base::TaskRunner> background_task_runner, 216 scoped_refptr<base::TaskRunner> background_task_runner,
182 const GrabWindowSnapshotAsyncCallback& callback) { 217 const GrabWindowSnapshotAsyncCallback& callback) {
(...skipping 11 matching lines...) Expand all
194 break; 229 break;
195 case gfx::Display::ROTATE_90: 230 case gfx::Display::ROTATE_90:
196 case gfx::Display::ROTATE_270: 231 case gfx::Display::ROTATE_270:
197 rotated_target_size = 232 rotated_target_size =
198 gfx::Size(target_size.height(), target_size.width()); 233 gfx::Size(target_size.height(), target_size.width());
199 break; 234 break;
200 }; 235 };
201 236
202 MakeAsyncCopyRequest(window, 237 MakeAsyncCopyRequest(window,
203 source_rect, 238 source_rect,
204 rotated_target_size, 239 base::Bind(&ScaleAndRotateCopyOutputResult,
205 background_task_runner, 240 callback,
206 callback); 241 rotated_target_size,
242 rotation,
243 background_task_runner));
207 } 244 }
208 245
209 void GrabWindowSnapshotAsync( 246 void GrabWindowSnapshotAsync(
210 gfx::NativeWindow window, 247 gfx::NativeWindow window,
211 const gfx::Rect& source_rect, 248 const gfx::Rect& source_rect,
212 scoped_refptr<base::TaskRunner> background_task_runner, 249 scoped_refptr<base::TaskRunner> background_task_runner,
213 const GrabWindowSnapshotAsyncCallback& callback) { 250 const GrabWindowSnapshotAsyncPNGCallback& callback) {
214 gfx::Size target_size = GetTargetBoundsFromWindow(window, source_rect).size(); 251 gfx::Size target_size = GetTargetBoundsFromWindow(window, source_rect).size();
215 MakeAsyncCopyRequest( 252 gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window)
216 window, source_rect, target_size, background_task_runner, callback); 253 ->GetDisplayNearestWindow(window)
254 .rotation();
255 MakeAsyncCopyRequest(window,
256 source_rect,
257 base::Bind(&ScaleRotateAndEncodeCopyOutputResult,
258 callback,
259 target_size,
260 rotation,
261 background_task_runner));
217 } 262 }
218 263
219 } // namespace ui 264 } // namespace ui
OLDNEW
« no previous file with comments | « ui/snapshot/snapshot_android.cc ('k') | ui/snapshot/snapshot_aura_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698