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

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