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

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

Issue 1582053002: Implement webview.captureVisibleRegion() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test so it waits for the first frame to be generated. 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 void PrepareTextureCopyOutputResult(
56 const gfx::Size& dst_size_in_pixel,
57 const SkColorType color_type,
58 const content::ReadbackRequestCallback& callback,
59 scoped_ptr<cc::CopyOutputResult> result) {
60 #if defined(OS_ANDROID) && !defined(USE_AURA)
61 // TODO(wjmaclean): See if there's an equivalent pathway for Android and
62 // implement it here.
63 callback.Run(SkBitmap(), content::READBACK_FAILED);
64 #else
65 DCHECK(result->HasTexture());
66 base::ScopedClosureRunner scoped_callback_runner(
67 base::Bind(callback, SkBitmap(), content::READBACK_FAILED));
68
69 // TODO(siva.gunturi): We should be able to validate the format here using
70 // GLHelper::IsReadbackConfigSupported before we processs the result.
71 // See crbug.com/415682 and crbug.com/415131.
72 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
73 if (!bitmap->tryAllocPixels(SkImageInfo::Make(
74 dst_size_in_pixel.width(), dst_size_in_pixel.height(), color_type,
75 kOpaque_SkAlphaType))) {
76 scoped_callback_runner.Reset(base::Bind(
77 callback, SkBitmap(), content::READBACK_BITMAP_ALLOCATION_FAILURE));
78 return;
79 }
80
81 content::ImageTransportFactory* factory =
82 content::ImageTransportFactory::GetInstance();
83 content::GLHelper* gl_helper = factory->GetGLHelper();
84 if (!gl_helper)
85 return;
86
87 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
88 new SkAutoLockPixels(*bitmap));
89 uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels());
90
91 cc::TextureMailbox texture_mailbox;
92 scoped_ptr<cc::SingleReleaseCallback> release_callback;
93 result->TakeTexture(&texture_mailbox, &release_callback);
94 DCHECK(texture_mailbox.IsTexture());
95
96 ignore_result(scoped_callback_runner.Release());
97
98 gl_helper->CropScaleReadbackAndCleanMailbox(
99 texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(),
100 gfx::Rect(result->size()), dst_size_in_pixel, pixels, color_type,
101 base::Bind(&CopyFromCompositingSurfaceFinished, callback,
102 base::Passed(&release_callback), base::Passed(&bitmap),
103 base::Passed(&bitmap_pixels_lock)),
104 content::GLHelper::SCALER_QUALITY_GOOD);
105 #endif
106 }
107
108 void PrepareBitmapCopyOutputResult(
109 const gfx::Size& dst_size_in_pixel,
110 const SkColorType preferred_color_type,
111 const content::ReadbackRequestCallback& callback,
112 scoped_ptr<cc::CopyOutputResult> result) {
113 SkColorType color_type = preferred_color_type;
114 if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) {
115 // Switch back to default colortype if format not supported.
116 color_type = kN32_SkColorType;
117 }
118 DCHECK(result->HasBitmap());
119 scoped_ptr<SkBitmap> source = result->TakeBitmap();
120 DCHECK(source);
121 SkBitmap scaled_bitmap;
122 if (source->width() != dst_size_in_pixel.width() ||
123 source->height() != dst_size_in_pixel.height()) {
124 scaled_bitmap = skia::ImageOperations::Resize(
125 *source, skia::ImageOperations::RESIZE_BEST, dst_size_in_pixel.width(),
126 dst_size_in_pixel.height());
127 } else {
128 scaled_bitmap = *source;
129 }
130 if (color_type == kN32_SkColorType) {
131 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType);
132 callback.Run(scaled_bitmap, content::READBACK_SUCCESS);
133 return;
134 }
135 DCHECK_EQ(color_type, kAlpha_8_SkColorType);
136 // The software path currently always returns N32 bitmap regardless of the
137 // |color_type| we ask for.
138 DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType);
139 // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|.
140 SkBitmap grayscale_bitmap;
141 bool success = grayscale_bitmap.tryAllocPixels(
142 SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height()));
143 if (!success) {
144 callback.Run(SkBitmap(), content::READBACK_BITMAP_ALLOCATION_FAILURE);
145 return;
146 }
147 SkCanvas canvas(grayscale_bitmap);
148 SkPaint paint;
149 skia::RefPtr<SkColorFilter> filter =
150 skia::AdoptRef(SkLumaColorFilter::Create());
151 paint.setColorFilter(filter.get());
152 canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint);
153 callback.Run(grayscale_bitmap, content::READBACK_SUCCESS);
154 }
155
156 } // namespace
157
17 namespace content { 158 namespace content {
18 159
19 scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() { 160 scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() {
20 #if defined(OS_ANDROID) && !defined(USE_AURA) 161 #if defined(OS_ANDROID) && !defined(USE_AURA)
21 return CompositorImpl::CreateSurfaceIdAllocator(); 162 return CompositorImpl::CreateSurfaceIdAllocator();
22 #else 163 #else
23 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 164 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
24 return factory->GetContextFactory()->CreateSurfaceIdAllocator(); 165 return factory->GetContextFactory()->CreateSurfaceIdAllocator();
25 #endif 166 #endif
26 } 167 }
27 168
28 cc::SurfaceManager* GetSurfaceManager() { 169 cc::SurfaceManager* GetSurfaceManager() {
29 #if defined(OS_ANDROID) && !defined(USE_AURA) 170 #if defined(OS_ANDROID) && !defined(USE_AURA)
30 return CompositorImpl::GetSurfaceManager(); 171 return CompositorImpl::GetSurfaceManager();
31 #else 172 #else
32 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 173 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
33 return factory->GetSurfaceManager(); 174 return factory->GetSurfaceManager();
34 #endif 175 #endif
35 } 176 }
36 177
178 void CopyFromCompositingSurfaceHasResult(
179 const gfx::Size& dst_size_in_pixel,
180 const SkColorType color_type,
181 const ReadbackRequestCallback& callback,
182 scoped_ptr<cc::CopyOutputResult> result) {
183 if (result->IsEmpty() || result->size().IsEmpty()) {
184 callback.Run(SkBitmap(), READBACK_FAILED);
185 return;
186 }
187
188 gfx::Size output_size_in_pixel;
189 if (dst_size_in_pixel.IsEmpty())
190 output_size_in_pixel = result->size();
191 else
192 output_size_in_pixel = dst_size_in_pixel;
193
194 if (result->HasTexture()) {
195 // GPU-accelerated path
196 PrepareTextureCopyOutputResult(output_size_in_pixel, color_type, callback,
197 std::move(result));
198 return;
199 }
200
201 DCHECK(result->HasBitmap());
202 // Software path
203 PrepareBitmapCopyOutputResult(output_size_in_pixel, color_type, callback,
204 std::move(result));
205 }
206
37 } // namespace content 207 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698