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

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

Issue 15004009: cc: Fix readback from non-root layers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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/gl_renderer_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 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>
(...skipping 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 return; 1797 return;
1798 1798
1799 FlushTextureQuadCache(); 1799 FlushTextureQuadCache();
1800 GLC(context_, context_->disable(GL_SCISSOR_TEST)); 1800 GLC(context_, context_->disable(GL_SCISSOR_TEST));
1801 is_scissor_enabled_ = false; 1801 is_scissor_enabled_ = false;
1802 } 1802 }
1803 1803
1804 void GLRenderer::CopyCurrentRenderPassToBitmap( 1804 void GLRenderer::CopyCurrentRenderPassToBitmap(
1805 DrawingFrame* frame, 1805 DrawingFrame* frame,
1806 const CopyRenderPassCallback& callback) { 1806 const CopyRenderPassCallback& callback) {
1807 GetFramebufferPixelsAsync(frame->current_render_pass->output_rect, callback); 1807 GetFramebufferPixelsAsync(frame->current_render_pass->output_rect,
1808 frame->flipped_y,
1809 callback);
1808 } 1810 }
1809 1811
1810 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { 1812 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) {
1811 transform.matrix().asColMajorf(gl_matrix); 1813 transform.matrix().asColMajorf(gl_matrix);
1812 } 1814 }
1813 1815
1814 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) { 1816 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) {
1815 if (quad_location == -1) 1817 if (quad_location == -1)
1816 return; 1818 return;
1817 1819
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 return; 2003 return;
2002 2004
2003 output_surface_->EnsureBackbuffer(); 2005 output_surface_->EnsureBackbuffer();
2004 is_backbuffer_discarded_ = false; 2006 is_backbuffer_discarded_ = false;
2005 } 2007 }
2006 2008
2007 void GLRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { 2009 void GLRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) {
2008 if (!pixels || rect.IsEmpty()) 2010 if (!pixels || rect.IsEmpty())
2009 return; 2011 return;
2010 2012
2013 // This function assumes that it is reading the root frame buffer.
2014 DCHECK(!current_framebuffer_lock_);
2015 bool flipped_y = FlippedFramebuffer();
2016
2011 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); 2017 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
2012 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), 2018 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2013 pending_read.Pass()); 2019 pending_read.Pass());
2014 2020
2015 // This is a syncronous call since the callback is null. 2021 // This is a syncronous call since the callback is null.
2016 DoGetFramebufferPixels(static_cast<uint8*>(pixels), 2022 DoGetFramebufferPixels(static_cast<uint8*>(pixels),
2017 rect, 2023 rect,
2024 flipped_y,
2018 AsyncGetFramebufferPixelsCleanupCallback()); 2025 AsyncGetFramebufferPixelsCleanupCallback());
2019 } 2026 }
2020 2027
2021 void GLRenderer::GetFramebufferPixelsAsync(gfx::Rect rect, 2028 void GLRenderer::GetFramebufferPixelsAsync(gfx::Rect rect,
2029 bool flipped_y,
2022 CopyRenderPassCallback callback) { 2030 CopyRenderPassCallback callback) {
2023 if (callback.is_null()) 2031 if (callback.is_null())
2024 return; 2032 return;
2025 if (rect.IsEmpty()) { 2033 if (rect.IsEmpty()) {
2026 callback.Run(scoped_ptr<SkBitmap>()); 2034 callback.Run(scoped_ptr<SkBitmap>());
2027 return; 2035 return;
2028 } 2036 }
2029 2037
2030 scoped_ptr<SkBitmap> bitmap(new SkBitmap); 2038 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
2031 bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); 2039 bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
(...skipping 10 matching lines...) Expand all
2042 base::Passed(&bitmap), 2050 base::Passed(&bitmap),
2043 base::Passed(&lock), 2051 base::Passed(&lock),
2044 callback); 2052 callback);
2045 2053
2046 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); 2054 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
2047 pending_read->copy_callback = callback; 2055 pending_read->copy_callback = callback;
2048 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), 2056 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
2049 pending_read.Pass()); 2057 pending_read.Pass());
2050 2058
2051 // This is an asyncronous call since the callback is not null. 2059 // This is an asyncronous call since the callback is not null.
2052 DoGetFramebufferPixels(pixels, rect, cleanup_callback); 2060 DoGetFramebufferPixels(pixels, rect, flipped_y, cleanup_callback);
2053 } 2061 }
2054 2062
2055 void GLRenderer::DoGetFramebufferPixels( 2063 void GLRenderer::DoGetFramebufferPixels(
2056 uint8* dest_pixels, 2064 uint8* dest_pixels,
2057 gfx::Rect rect, 2065 gfx::Rect rect,
2066 bool flipped_y,
2058 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) { 2067 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) {
2059 DCHECK(rect.right() <= ViewportWidth()); 2068 DCHECK(rect.right() <= ViewportWidth());
2060 DCHECK(rect.bottom() <= ViewportHeight()); 2069 DCHECK(rect.bottom() <= ViewportHeight());
2061 2070
2062 bool is_async = !cleanup_callback.is_null(); 2071 bool is_async = !cleanup_callback.is_null();
2063 2072
2064 MakeContextCurrent(); 2073 MakeContextCurrent();
2065 2074
2066 bool do_workaround = NeedsIOSurfaceReadbackWorkaround(); 2075 bool do_workaround = NeedsIOSurfaceReadbackWorkaround();
2067 2076
(...skipping 22 matching lines...) Expand all
2090 context_->texParameteri( 2099 context_->texParameteri(
2091 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); 2100 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
2092 // Copy the contents of the current (IOSurface-backed) framebuffer into a 2101 // Copy the contents of the current (IOSurface-backed) framebuffer into a
2093 // temporary texture. 2102 // temporary texture.
2094 GLC(context_, 2103 GLC(context_,
2095 context_->copyTexImage2D(GL_TEXTURE_2D, 2104 context_->copyTexImage2D(GL_TEXTURE_2D,
2096 0, 2105 0,
2097 GL_RGBA, 2106 GL_RGBA,
2098 0, 2107 0,
2099 0, 2108 0,
2100 ViewportSize().width(), 2109 current_framebuffer_size_.width(),
2101 ViewportSize().height(), 2110 current_framebuffer_size_.height(),
2102 0)); 2111 0));
2103 temporary_fbo = context_->createFramebuffer(); 2112 temporary_fbo = context_->createFramebuffer();
2104 // Attach this texture to an FBO, and perform the readback from that FBO. 2113 // Attach this texture to an FBO, and perform the readback from that FBO.
2105 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, temporary_fbo)); 2114 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, temporary_fbo));
2106 GLC(context_, 2115 GLC(context_,
2107 context_->framebufferTexture2D(GL_FRAMEBUFFER, 2116 context_->framebufferTexture2D(GL_FRAMEBUFFER,
2108 GL_COLOR_ATTACHMENT0, 2117 GL_COLOR_ATTACHMENT0,
2109 GL_TEXTURE_2D, 2118 GL_TEXTURE_2D,
2110 temporary_texture, 2119 temporary_texture,
2111 0)); 2120 0));
2112 2121
2113 DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) == 2122 DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) ==
2114 GL_FRAMEBUFFER_COMPLETE); 2123 GL_FRAMEBUFFER_COMPLETE);
2115 } 2124 }
2116 2125
2117 unsigned buffer = context_->createBuffer(); 2126 unsigned buffer = context_->createBuffer();
2118 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2127 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2119 buffer)); 2128 buffer));
2120 GLC(context_, context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2129 GLC(context_, context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2121 4 * rect.size().GetArea(), 2130 4 * rect.size().GetArea(),
2122 NULL, 2131 NULL,
2123 GL_STREAM_READ)); 2132 GL_STREAM_READ));
2124 2133
2125 GLC(context_, 2134 GLC(context_,
2126 context_->readPixels(rect.x(), 2135 context_->readPixels(rect.x(),
2127 ViewportSize().height() - rect.bottom(), 2136 current_framebuffer_size_.height() - rect.bottom(),
2128 rect.width(), 2137 rect.width(),
2129 rect.height(), 2138 rect.height(),
2130 GL_RGBA, 2139 GL_RGBA,
2131 GL_UNSIGNED_BYTE, 2140 GL_UNSIGNED_BYTE,
2132 NULL)); 2141 NULL));
2133 2142
2134 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2143 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2135 0)); 2144 0));
2136 2145
2137 if (do_workaround) { 2146 if (do_workaround) {
2138 // Clean up. 2147 // Clean up.
2139 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); 2148 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0));
2140 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); 2149 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0));
2141 GLC(context_, context_->deleteFramebuffer(temporary_fbo)); 2150 GLC(context_, context_->deleteFramebuffer(temporary_fbo));
2142 GLC(context_, context_->deleteTexture(temporary_texture)); 2151 GLC(context_, context_->deleteTexture(temporary_texture));
2143 } 2152 }
2144 2153
2145 base::Closure finished_callback = 2154 base::Closure finished_callback =
2146 base::Bind(&GLRenderer::FinishedReadback, 2155 base::Bind(&GLRenderer::FinishedReadback,
2147 base::Unretained(this), 2156 base::Unretained(this),
2148 cleanup_callback, 2157 cleanup_callback,
2149 buffer, 2158 buffer,
2150 dest_pixels, 2159 dest_pixels,
2151 rect.size()); 2160 rect.size(),
2161 flipped_y);
2152 // Save the finished_callback so it can be cancelled. 2162 // Save the finished_callback so it can be cancelled.
2153 pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset( 2163 pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset(
2154 finished_callback); 2164 finished_callback);
2155 2165
2156 // Save the buffer to verify the callbacks happen in the expected order. 2166 // Save the buffer to verify the callbacks happen in the expected order.
2157 pending_async_read_pixels_.front()->buffer = buffer; 2167 pending_async_read_pixels_.front()->buffer = buffer;
2158 2168
2159 if (is_async) { 2169 if (is_async) {
2160 unsigned sync_point = context_->insertSyncPoint(); 2170 unsigned sync_point = context_->insertSyncPoint();
2161 SyncPointHelper::SignalSyncPoint( 2171 SyncPointHelper::SignalSyncPoint(
2162 context_, 2172 context_,
2163 sync_point, 2173 sync_point,
2164 finished_callback); 2174 finished_callback);
2165 } else { 2175 } else {
2166 resource_provider_->Finish(); 2176 resource_provider_->Finish();
2167 finished_callback.Run(); 2177 finished_callback.Run();
2168 } 2178 }
2169 2179
2170 EnforceMemoryPolicy(); 2180 EnforceMemoryPolicy();
2171 } 2181 }
2172 2182
2173 void GLRenderer::FinishedReadback( 2183 void GLRenderer::FinishedReadback(
2174 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback, 2184 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback,
2175 unsigned source_buffer, 2185 unsigned source_buffer,
2176 uint8* dest_pixels, 2186 uint8* dest_pixels,
2177 gfx::Size size) { 2187 gfx::Size size,
2188 bool flipped_y) {
2178 DCHECK(!pending_async_read_pixels_.empty()); 2189 DCHECK(!pending_async_read_pixels_.empty());
2179 DCHECK_EQ(source_buffer, pending_async_read_pixels_.back()->buffer); 2190 DCHECK_EQ(source_buffer, pending_async_read_pixels_.back()->buffer);
2180 2191
2181 uint8* src_pixels = NULL; 2192 uint8* src_pixels = NULL;
2182 2193
2183 if (source_buffer != 0) { 2194 if (source_buffer != 0) {
2184 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2195 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2185 source_buffer)); 2196 source_buffer));
2186 src_pixels = static_cast<uint8*>( 2197 src_pixels = static_cast<uint8*>(
2187 context_->mapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 2198 context_->mapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
2188 GL_READ_ONLY)); 2199 GL_READ_ONLY));
2189 2200
2190 if (src_pixels) { 2201 if (src_pixels) {
2191 size_t row_bytes = size.width() * 4; 2202 size_t row_bytes = size.width() * 4;
2192 int num_rows = size.height(); 2203 int num_rows = size.height();
2193 size_t total_bytes = num_rows * row_bytes; 2204 size_t total_bytes = num_rows * row_bytes;
2194 for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) { 2205 for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) {
2195 // Flip Y axis. 2206 // Flip Y axis.
2196 size_t src_y = total_bytes - dest_y - row_bytes; 2207 size_t src_y = flipped_y ? total_bytes - dest_y - row_bytes
2208 : dest_y;
2197 // Swizzle BGRA -> RGBA. 2209 // Swizzle BGRA -> RGBA.
2198 for (size_t x = 0; x < row_bytes; x += 4) { 2210 for (size_t x = 0; x < row_bytes; x += 4) {
2199 dest_pixels[dest_y + (x + 0)] = src_pixels[src_y + (x + 2)]; 2211 dest_pixels[dest_y + (x + 0)] = src_pixels[src_y + (x + 2)];
2200 dest_pixels[dest_y + (x + 1)] = src_pixels[src_y + (x + 1)]; 2212 dest_pixels[dest_y + (x + 1)] = src_pixels[src_y + (x + 1)];
2201 dest_pixels[dest_y + (x + 2)] = src_pixels[src_y + (x + 0)]; 2213 dest_pixels[dest_y + (x + 2)] = src_pixels[src_y + (x + 0)];
2202 dest_pixels[dest_y + (x + 3)] = src_pixels[src_y + (x + 3)]; 2214 dest_pixels[dest_y + (x + 3)] = src_pixels[src_y + (x + 3)];
2203 } 2215 }
2204 } 2216 }
2205 2217
2206 GLC(context_, context_->unmapBufferCHROMIUM( 2218 GLC(context_, context_->unmapBufferCHROMIUM(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { 2282 void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
2271 current_framebuffer_lock_.reset(); 2283 current_framebuffer_lock_.reset();
2272 output_surface_->BindFramebuffer(); 2284 output_surface_->BindFramebuffer();
2273 } 2285 }
2274 2286
2275 bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame, 2287 bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
2276 const ScopedResource* texture, 2288 const ScopedResource* texture,
2277 gfx::Rect framebuffer_rect) { 2289 gfx::Rect framebuffer_rect) {
2278 DCHECK(texture->id()); 2290 DCHECK(texture->id());
2279 2291
2292 current_framebuffer_lock_.reset();
2293
2280 GLC(context_, 2294 GLC(context_,
2281 context_->bindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_)); 2295 context_->bindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_));
2282 current_framebuffer_lock_ = 2296 current_framebuffer_lock_ =
2283 make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL( 2297 make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL(
2284 resource_provider_, texture->id())); 2298 resource_provider_, texture->id()));
2285 unsigned texture_id = current_framebuffer_lock_->texture_id(); 2299 unsigned texture_id = current_framebuffer_lock_->texture_id();
2286 GLC(context_, 2300 GLC(context_,
2287 context_->framebufferTexture2D( 2301 context_->framebufferTexture2D(
2288 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0)); 2302 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0));
2289 2303
(...skipping 17 matching lines...) Expand all
2307 scissor_rect_ = scissor_rect; 2321 scissor_rect_ = scissor_rect;
2308 FlushTextureQuadCache(); 2322 FlushTextureQuadCache();
2309 GLC(context_, 2323 GLC(context_,
2310 context_->scissor(scissor_rect.x(), 2324 context_->scissor(scissor_rect.x(),
2311 scissor_rect.y(), 2325 scissor_rect.y(),
2312 scissor_rect.width(), 2326 scissor_rect.width(),
2313 scissor_rect.height())); 2327 scissor_rect.height()));
2314 } 2328 }
2315 2329
2316 void GLRenderer::SetDrawViewportSize(gfx::Size viewport_size) { 2330 void GLRenderer::SetDrawViewportSize(gfx::Size viewport_size) {
2331 current_framebuffer_size_ = viewport_size;
2317 GLC(context_, 2332 GLC(context_,
2318 context_->viewport(0, 0, viewport_size.width(), viewport_size.height())); 2333 context_->viewport(0, 0, viewport_size.width(), viewport_size.height()));
2319 } 2334 }
2320 2335
2321 bool GLRenderer::MakeContextCurrent() { return context_->makeContextCurrent(); } 2336 bool GLRenderer::MakeContextCurrent() { return context_->makeContextCurrent(); }
2322 2337
2323 bool GLRenderer::InitializeSharedObjects() { 2338 bool GLRenderer::InitializeSharedObjects() {
2324 TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects"); 2339 TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects");
2325 MakeContextCurrent(); 2340 MakeContextCurrent();
2326 2341
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_); 2797 resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_);
2783 2798
2784 ReleaseRenderPassTextures(); 2799 ReleaseRenderPassTextures();
2785 } 2800 }
2786 2801
2787 bool GLRenderer::IsContextLost() { 2802 bool GLRenderer::IsContextLost() {
2788 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); 2803 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR);
2789 } 2804 }
2790 2805
2791 } // namespace cc 2806 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/gl_renderer.h ('k') | cc/output/gl_renderer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698