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

Side by Side Diff: cc/output/gl_renderer.cc

Issue 15435003: cc: Add CopyAsBitmapRequest class to hold the readback callback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nolint Created 7 years, 7 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 | « cc/output/gl_renderer.h ('k') | cc/output/software_renderer.h » ('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 2010 The Chromium Authors. All rights reserved. 1 // Copyright 2010 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 "cc/output/gl_renderer.h" 5 #include "cc/output/gl_renderer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/debug/trace_event.h" 13 #include "base/debug/trace_event.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "base/strings/string_split.h" 16 #include "base/strings/string_split.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "cc/base/math_util.h" 18 #include "cc/base/math_util.h"
19 #include "cc/layers/video_layer_impl.h" 19 #include "cc/layers/video_layer_impl.h"
20 #include "cc/output/compositor_frame.h" 20 #include "cc/output/compositor_frame.h"
21 #include "cc/output/compositor_frame_metadata.h" 21 #include "cc/output/compositor_frame_metadata.h"
22 #include "cc/output/context_provider.h" 22 #include "cc/output/context_provider.h"
23 #include "cc/output/copy_output_request.h"
23 #include "cc/output/geometry_binding.h" 24 #include "cc/output/geometry_binding.h"
24 #include "cc/output/gl_frame_data.h" 25 #include "cc/output/gl_frame_data.h"
25 #include "cc/output/output_surface.h" 26 #include "cc/output/output_surface.h"
26 #include "cc/output/render_surface_filters.h" 27 #include "cc/output/render_surface_filters.h"
27 #include "cc/quads/picture_draw_quad.h" 28 #include "cc/quads/picture_draw_quad.h"
28 #include "cc/quads/render_pass.h" 29 #include "cc/quads/render_pass.h"
29 #include "cc/quads/stream_video_draw_quad.h" 30 #include "cc/quads/stream_video_draw_quad.h"
30 #include "cc/quads/texture_draw_quad.h" 31 #include "cc/quads/texture_draw_quad.h"
31 #include "cc/resources/layer_quad.h" 32 #include "cc/resources/layer_quad.h"
32 #include "cc/resources/priority_calculator.h" 33 #include "cc/resources/priority_calculator.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 88
88 // Smallest unit that impact anti-aliasing output. We use this to 89 // Smallest unit that impact anti-aliasing output. We use this to
89 // determine when anti-aliasing is unnecessary. 90 // determine when anti-aliasing is unnecessary.
90 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; 91 const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
91 92
92 } // anonymous namespace 93 } // anonymous namespace
93 94
94 struct GLRenderer::PendingAsyncReadPixels { 95 struct GLRenderer::PendingAsyncReadPixels {
95 PendingAsyncReadPixels() : buffer(0) {} 96 PendingAsyncReadPixels() : buffer(0) {}
96 97
97 CopyRenderPassCallback copy_callback; 98 scoped_ptr<CopyOutputRequest> copy_request;
98 base::CancelableClosure finished_read_pixels_callback; 99 base::CancelableClosure finished_read_pixels_callback;
99 unsigned buffer; 100 unsigned buffer;
100 101
101 private: 102 private:
102 DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels); 103 DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels);
103 }; 104 };
104 105
105 scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, 106 scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client,
106 OutputSurface* output_surface, 107 OutputSurface* output_surface,
107 ResourceProvider* resource_provider, 108 ResourceProvider* resource_provider,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 return; 217 return;
217 218
218 gr_context_ = skia::AdoptRef(GrContext::Create( 219 gr_context_ = skia::AdoptRef(GrContext::Create(
219 kOpenGL_GrBackend, 220 kOpenGL_GrBackend,
220 reinterpret_cast<GrBackendContext>(interface.get()))); 221 reinterpret_cast<GrBackendContext>(interface.get())));
221 ReinitializeGrCanvas(); 222 ReinitializeGrCanvas();
222 } 223 }
223 224
224 GLRenderer::~GLRenderer() { 225 GLRenderer::~GLRenderer() {
225 while (!pending_async_read_pixels_.empty()) { 226 while (!pending_async_read_pixels_.empty()) {
226 pending_async_read_pixels_.back()->finished_read_pixels_callback.Cancel(); 227 PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back();
227 pending_async_read_pixels_.back()->copy_callback.Run( 228 pending_read->finished_read_pixels_callback.Cancel();
228 scoped_ptr<SkBitmap>());
229 pending_async_read_pixels_.pop_back(); 229 pending_async_read_pixels_.pop_back();
230 } 230 }
231 231
232 context_->setMemoryAllocationChangedCallbackCHROMIUM(NULL); 232 context_->setMemoryAllocationChangedCallbackCHROMIUM(NULL);
233 CleanupSharedObjects(); 233 CleanupSharedObjects();
234 } 234 }
235 235
236 const RendererCapabilities& GLRenderer::Capabilities() const { 236 const RendererCapabilities& GLRenderer::Capabilities() const {
237 return capabilities_; 237 return capabilities_;
238 } 238 }
(...skipping 1623 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 if (!is_scissor_enabled_) 1862 if (!is_scissor_enabled_)
1863 return; 1863 return;
1864 1864
1865 FlushTextureQuadCache(); 1865 FlushTextureQuadCache();
1866 GLC(context_, context_->disable(GL_SCISSOR_TEST)); 1866 GLC(context_, context_->disable(GL_SCISSOR_TEST));
1867 is_scissor_enabled_ = false; 1867 is_scissor_enabled_ = false;
1868 } 1868 }
1869 1869
1870 void GLRenderer::CopyCurrentRenderPassToBitmap( 1870 void GLRenderer::CopyCurrentRenderPassToBitmap(
1871 DrawingFrame* frame, 1871 DrawingFrame* frame,
1872 const CopyRenderPassCallback& callback) { 1872 scoped_ptr<CopyOutputRequest> request) {
1873 GetFramebufferPixelsAsync(frame->current_render_pass->output_rect, 1873 GetFramebufferPixelsAsync(frame->current_render_pass->output_rect,
1874 frame->flipped_y, 1874 frame->flipped_y,
1875 callback); 1875 request.Pass());
1876 } 1876 }
1877 1877
1878 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { 1878 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) {
1879 transform.matrix().asColMajorf(gl_matrix); 1879 transform.matrix().asColMajorf(gl_matrix);
1880 } 1880 }
1881 1881
1882 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) { 1882 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) {
1883 if (quad_location == -1) 1883 if (quad_location == -1)
1884 return; 1884 return;
1885 1885
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), 2084 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2085 pending_read.Pass()); 2085 pending_read.Pass());
2086 2086
2087 // This is a syncronous call since the callback is null. 2087 // This is a syncronous call since the callback is null.
2088 DoGetFramebufferPixels(static_cast<uint8*>(pixels), 2088 DoGetFramebufferPixels(static_cast<uint8*>(pixels),
2089 rect, 2089 rect,
2090 flipped_y, 2090 flipped_y,
2091 AsyncGetFramebufferPixelsCleanupCallback()); 2091 AsyncGetFramebufferPixelsCleanupCallback());
2092 } 2092 }
2093 2093
2094 void GLRenderer::GetFramebufferPixelsAsync(gfx::Rect rect, 2094 void GLRenderer::GetFramebufferPixelsAsync(
2095 bool flipped_y, 2095 gfx::Rect rect, bool flipped_y, scoped_ptr<CopyOutputRequest> request) {
2096 CopyRenderPassCallback callback) { 2096 DCHECK(!request->IsEmpty());
2097 if (callback.is_null()) 2097 if (request->IsEmpty())
2098 return; 2098 return;
2099 if (rect.IsEmpty()) { 2099 if (rect.IsEmpty())
2100 callback.Run(scoped_ptr<SkBitmap>());
2101 return; 2100 return;
2102 }
2103 2101
2104 scoped_ptr<SkBitmap> bitmap(new SkBitmap); 2102 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
2105 bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); 2103 bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
2106 bitmap->allocPixels(); 2104 bitmap->allocPixels();
2107 2105
2108 scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap)); 2106 scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
2109 2107
2110 // Save a pointer to the pixels, the bitmap is owned by the cleanup_callback. 2108 // Save a pointer to the pixels, the bitmap is owned by the cleanup_callback.
2111 uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); 2109 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
2112 2110
2113 AsyncGetFramebufferPixelsCleanupCallback cleanup_callback = base::Bind( 2111 AsyncGetFramebufferPixelsCleanupCallback cleanup_callback = base::Bind(
2114 &GLRenderer::PassOnSkBitmap, 2112 &GLRenderer::PassOnSkBitmap,
2115 base::Unretained(this), 2113 base::Unretained(this),
2116 base::Passed(&bitmap), 2114 base::Passed(&bitmap),
2117 base::Passed(&lock), 2115 base::Passed(&lock));
2118 callback);
2119 2116
2120 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); 2117 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
2121 pending_read->copy_callback = callback; 2118 pending_read->copy_request = request.Pass();
2122 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), 2119 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2123 pending_read.Pass()); 2120 pending_read.Pass());
2124 2121
2125 // This is an asyncronous call since the callback is not null. 2122 // This is an asyncronous call since the callback is not null.
2126 DoGetFramebufferPixels(pixels, rect, flipped_y, cleanup_callback); 2123 DoGetFramebufferPixels(pixels, rect, flipped_y, cleanup_callback);
2127 } 2124 }
2128 2125
2129 void GLRenderer::DoGetFramebufferPixels( 2126 void GLRenderer::DoGetFramebufferPixels(
2130 uint8* dest_pixels, 2127 uint8* dest_pixels,
2131 gfx::Rect rect, 2128 gfx::Rect rect,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 EnforceMemoryPolicy(); 2243 EnforceMemoryPolicy();
2247 } 2244 }
2248 2245
2249 void GLRenderer::FinishedReadback( 2246 void GLRenderer::FinishedReadback(
2250 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback, 2247 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback,
2251 unsigned source_buffer, 2248 unsigned source_buffer,
2252 uint8* dest_pixels, 2249 uint8* dest_pixels,
2253 gfx::Size size, 2250 gfx::Size size,
2254 bool flipped_y) { 2251 bool flipped_y) {
2255 DCHECK(!pending_async_read_pixels_.empty()); 2252 DCHECK(!pending_async_read_pixels_.empty());
2256 DCHECK_EQ(source_buffer, pending_async_read_pixels_.back()->buffer); 2253
2254 PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back();
2255 // Make sure we service the readbacks in order.
2256 DCHECK_EQ(source_buffer, current_read->buffer);
2257 2257
2258 uint8* src_pixels = NULL; 2258 uint8* src_pixels = NULL;
2259 2259
2260 if (source_buffer != 0) { 2260 if (source_buffer != 0) {
2261 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2261 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2262 source_buffer)); 2262 source_buffer));
2263 src_pixels = static_cast<uint8*>( 2263 src_pixels = static_cast<uint8*>(
2264 context_->mapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2264 context_->mapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2265 GL_READ_ONLY)); 2265 GL_READ_ONLY));
2266 2266
(...skipping 18 matching lines...) Expand all
2285 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM)); 2285 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM));
2286 } 2286 }
2287 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2287 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2288 0)); 2288 0));
2289 GLC(context_, context_->deleteBuffer(source_buffer)); 2289 GLC(context_, context_->deleteBuffer(source_buffer));
2290 } 2290 }
2291 2291
2292 // TODO(danakj): This can go away when synchronous readback is no more and its 2292 // TODO(danakj): This can go away when synchronous readback is no more and its
2293 // contents can just move here. 2293 // contents can just move here.
2294 if (!cleanup_callback.is_null()) 2294 if (!cleanup_callback.is_null())
2295 cleanup_callback.Run(src_pixels != NULL); 2295 cleanup_callback.Run(current_read->copy_request.Pass(), src_pixels != NULL);
2296 2296
2297 pending_async_read_pixels_.pop_back(); 2297 pending_async_read_pixels_.pop_back();
2298 } 2298 }
2299 2299
2300 void GLRenderer::PassOnSkBitmap( 2300 void GLRenderer::PassOnSkBitmap(
2301 scoped_ptr<SkBitmap> bitmap, 2301 scoped_ptr<SkBitmap> bitmap,
2302 scoped_ptr<SkAutoLockPixels> lock, 2302 scoped_ptr<SkAutoLockPixels> lock,
2303 const CopyRenderPassCallback& callback, 2303 scoped_ptr<CopyOutputRequest> request,
2304 bool success) { 2304 bool success) {
2305 DCHECK(callback.Equals(pending_async_read_pixels_.back()->copy_callback)); 2305 DCHECK(request->HasBitmapRequest());
2306 2306
2307 lock.reset(); 2307 lock.reset();
2308 if (success) 2308 if (success)
2309 callback.Run(bitmap.Pass()); 2309 request->SendBitmapResult(bitmap.Pass());
2310 else
2311 callback.Run(scoped_ptr<SkBitmap>());
2312 } 2310 }
2313 2311
2314 bool GLRenderer::GetFramebufferTexture(ScopedResource* texture, 2312 bool GLRenderer::GetFramebufferTexture(ScopedResource* texture,
2315 gfx::Rect device_rect) { 2313 gfx::Rect device_rect) {
2316 DCHECK(!texture->id() || (texture->size() == device_rect.size() && 2314 DCHECK(!texture->id() || (texture->size() == device_rect.size() &&
2317 texture->format() == GL_RGB)); 2315 texture->format() == GL_RGB));
2318 2316
2319 if (!texture->id() && !texture->Allocate(device_rect.size(), 2317 if (!texture->id() && !texture->Allocate(device_rect.size(),
2320 GL_RGB, 2318 GL_RGB,
2321 ResourceProvider::TextureUsageAny)) 2319 ResourceProvider::TextureUsageAny))
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
2908 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas 2906 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas
2909 // implementation. 2907 // implementation.
2910 return gr_context_ && context_->getContextAttributes().stencil; 2908 return gr_context_ && context_->getContextAttributes().stencil;
2911 } 2909 }
2912 2910
2913 bool GLRenderer::IsContextLost() { 2911 bool GLRenderer::IsContextLost() {
2914 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); 2912 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR);
2915 } 2913 }
2916 2914
2917 } // namespace cc 2915 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/gl_renderer.h ('k') | cc/output/software_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698