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

Side by Side Diff: content/browser/compositor/surface_utils.cc

Issue 1635513003: Implement webview.captureVisibleRegion() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Save bug number to surface_utils.cc. Created 4 years, 10 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "content/browser/compositor/surface_utils.h" 5 #include "content/browser/compositor/surface_utils.h"
6 6
7 #include "base/callback_helpers.h"
8 #include "base/memory/ref_counted.h"
7 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "cc/output/copy_output_result.h"
11 #include "cc/resources/single_release_callback.h"
8 #include "cc/surfaces/surface_id_allocator.h" 12 #include "cc/surfaces/surface_id_allocator.h"
13 #include "content/common/gpu/client/gl_helper.h"
14 #include "skia/ext/image_operations.h"
15 #include "skia/ext/refptr.h"
16 #include "third_party/skia/include/core/SkCanvas.h"
17 #include "third_party/skia/include/core/SkColorFilter.h"
18 #include "third_party/skia/include/core/SkPaint.h"
19 #include "third_party/skia/include/effects/SkLumaColorFilter.h"
20 #include "ui/gfx/geometry/rect.h"
9 21
10 #if defined(OS_ANDROID) && !defined(USE_AURA) 22 #if defined(OS_ANDROID) && !defined(USE_AURA)
11 #include "content/browser/renderer_host/compositor_impl_android.h" 23 #include "content/browser/renderer_host/compositor_impl_android.h"
12 #else 24 #else
13 #include "content/browser/compositor/image_transport_factory.h" 25 #include "content/browser/compositor/image_transport_factory.h"
14 #include "ui/compositor/compositor.h" 26 #include "ui/compositor/compositor.h"
15 #endif 27 #endif
16 28
29 namespace {
30
31 #if !defined(OS_ANDROID) || defined(USE_AURA)
32 void CopyFromCompositingSurfaceFinished(
33 const content::ReadbackRequestCallback& callback,
34 scoped_ptr<cc::SingleReleaseCallback> release_callback,
35 scoped_ptr<SkBitmap> bitmap,
36 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
37 bool result) {
38 bitmap_pixels_lock.reset();
39
40 gpu::SyncToken sync_token;
41 if (result) {
42 content::GLHelper* gl_helper =
43 content::ImageTransportFactory::GetInstance()->GetGLHelper();
44 if (gl_helper)
45 gl_helper->GenerateSyncToken(&sync_token);
46 }
47 const bool lost_resource = !sync_token.HasData();
48 release_callback->Run(sync_token, lost_resource);
49
50 callback.Run(*bitmap,
51 result ? content::READBACK_SUCCESS : content::READBACK_FAILED);
52 }
53 #endif
54
55 // TODO(wjmaclean): There is significant overlap between
56 // PrepareTextureCopyOutputResult and CopyFromCompositingSurfaceFinished in
57 // this file, and the versions in RenderWidgetHostViewAndroid. They should
58 // be merged. See https://crbug.com/582955
59 void PrepareTextureCopyOutputResult(
60 const gfx::Size& dst_size_in_pixel,
61 const SkColorType color_type,
62 const content::ReadbackRequestCallback& callback,
63 scoped_ptr<cc::CopyOutputResult> result) {
64 #if defined(OS_ANDROID) && !defined(USE_AURA)
65 // TODO(wjmaclean): See if there's an equivalent pathway for Android and
66 // implement it here.
67 callback.Run(SkBitmap(), content::READBACK_FAILED);
68 #else
69 DCHECK(result->HasTexture());
70 base::ScopedClosureRunner scoped_callback_runner(
71 base::Bind(callback, SkBitmap(), content::READBACK_FAILED));
72
73 // TODO(siva.gunturi): We should be able to validate the format here using
74 // GLHelper::IsReadbackConfigSupported before we processs the result.
75 // See crbug.com/415682 and crbug.com/415131.
76 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
77 if (!bitmap->tryAllocPixels(SkImageInfo::Make(
78 dst_size_in_pixel.width(), dst_size_in_pixel.height(), color_type,
79 kOpaque_SkAlphaType))) {
80 scoped_callback_runner.Reset(base::Bind(
81 callback, SkBitmap(), content::READBACK_BITMAP_ALLOCATION_FAILURE));
82 return;
83 }
84
85 content::ImageTransportFactory* factory =
86 content::ImageTransportFactory::GetInstance();
87 content::GLHelper* gl_helper = factory->GetGLHelper();
88 if (!gl_helper)
89 return;
90
91 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
92 new SkAutoLockPixels(*bitmap));
93 uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
94
95 cc::TextureMailbox texture_mailbox;
96 scoped_ptr<cc::SingleReleaseCallback> release_callback;
97 result->TakeTexture(&texture_mailbox, &release_callback);
98 DCHECK(texture_mailbox.IsTexture());
99
100 ignore_result(scoped_callback_runner.Release());
101
102 gl_helper->CropScaleReadbackAndCleanMailbox(
103 texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
104 gfx::Rect(result->size()), dst_size_in_pixel, pixels, color_type,
105 base::Bind(&CopyFromCompositingSurfaceFinished, callback,
106 base::Passed(&release_callback), base::Passed(&bitmap),
107 base::Passed(&bitmap_pixels_lock)),
108 content::GLHelper::SCALER_QUALITY_GOOD);
109 #endif
110 }
111
112 void PrepareBitmapCopyOutputResult(
113 const gfx::Size& dst_size_in_pixel,
114 const SkColorType preferred_color_type,
115 const content::ReadbackRequestCallback& callback,
116 scoped_ptr<cc::CopyOutputResult> result) {
117 SkColorType color_type = preferred_color_type;
118 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) {
119 // Switch back to default colortype if format not supported.
120 color_type = kN32_SkColorType;
121 }
122 DCHECK(result->HasBitmap());
123 scoped_ptr<SkBitmap> source = result->TakeBitmap();
124 DCHECK(source);
125 SkBitmap scaled_bitmap;
126 if (source->width() != dst_size_in_pixel.width() ||
127 source->height() != dst_size_in_pixel.height()) {
128 scaled_bitmap = skia::ImageOperations::Resize(
129 *source, skia::ImageOperations::RESIZE_BEST, dst_size_in_pixel.width(),
130 dst_size_in_pixel.height());
131 } else {
132 scaled_bitmap = *source;
133 }
134 if (color_type == kN32_SkColorType) {
135 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType);
136 callback.Run(scaled_bitmap, content::READBACK_SUCCESS);
137 return;
138 }
139 DCHECK_EQ(color_type, kAlpha_8_SkColorType);
140 // The software path currently always returns N32 bitmap regardless of the
141 // |color_type| we ask for.
142 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType);
143 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|.
144 SkBitmap grayscale_bitmap;
145 bool success = grayscale_bitmap.tryAllocPixels(
146 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height()));
147 if (!success) {
148 callback.Run(SkBitmap(), content::READBACK_BITMAP_ALLOCATION_FAILURE);
149 return;
150 }
151 SkCanvas canvas(grayscale_bitmap);
152 SkPaint paint;
153 skia::RefPtr<SkColorFilter> filter =
154 skia::AdoptRef(SkLumaColorFilter::Create());
155 paint.setColorFilter(filter.get());
156 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint);
157 callback.Run(grayscale_bitmap, content::READBACK_SUCCESS);
158 }
159
160 } // namespace
161
17 namespace content { 162 namespace content {
18 163
19 scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() { 164 scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() {
20 #if defined(OS_ANDROID) && !defined(USE_AURA) 165 #if defined(OS_ANDROID) && !defined(USE_AURA)
21 return CompositorImpl::CreateSurfaceIdAllocator(); 166 return CompositorImpl::CreateSurfaceIdAllocator();
22 #else 167 #else
23 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 168 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
24 return factory->GetContextFactory()->CreateSurfaceIdAllocator(); 169 return factory->GetContextFactory()->CreateSurfaceIdAllocator();
25 #endif 170 #endif
26 } 171 }
27 172
28 cc::SurfaceManager* GetSurfaceManager() { 173 cc::SurfaceManager* GetSurfaceManager() {
29 #if defined(OS_ANDROID) && !defined(USE_AURA) 174 #if defined(OS_ANDROID) && !defined(USE_AURA)
30 return CompositorImpl::GetSurfaceManager(); 175 return CompositorImpl::GetSurfaceManager();
31 #else 176 #else
32 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 177 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
33 return factory->GetSurfaceManager(); 178 return factory->GetSurfaceManager();
34 #endif 179 #endif
35 } 180 }
36 181
182 void CopyFromCompositingSurfaceHasResult(
183 const gfx::Size& dst_size_in_pixel,
184 const SkColorType color_type,
185 const ReadbackRequestCallback& callback,
186 scoped_ptr<cc::CopyOutputResult> result) {
187 if (result->IsEmpty() || result->size().IsEmpty()) {
188 callback.Run(SkBitmap(), READBACK_FAILED);
189 return;
190 }
191
192 gfx::Size output_size_in_pixel;
193 if (dst_size_in_pixel.IsEmpty())
194 output_size_in_pixel = result->size();
195 else
196 output_size_in_pixel = dst_size_in_pixel;
197
198 if (result->HasTexture()) {
199 // GPU-accelerated path
200 PrepareTextureCopyOutputResult(output_size_in_pixel, color_type, callback,
201 std::move(result));
202 return;
203 }
204
205 DCHECK(result->HasBitmap());
206 // Software path
207 PrepareBitmapCopyOutputResult(output_size_in_pixel, color_type, callback,
208 std::move(result));
209 }
210
37 } // namespace content 211 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/compositor/surface_utils.h ('k') | content/browser/frame_host/render_widget_host_view_child_frame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698