Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "cc/output/gl_frame_data.h" | 23 #include "cc/output/gl_frame_data.h" |
| 24 #include "cc/output/output_surface.h" | 24 #include "cc/output/output_surface.h" |
| 25 #include "cc/output/render_surface_filters.h" | 25 #include "cc/output/render_surface_filters.h" |
| 26 #include "cc/quads/picture_draw_quad.h" | 26 #include "cc/quads/picture_draw_quad.h" |
| 27 #include "cc/quads/render_pass.h" | 27 #include "cc/quads/render_pass.h" |
| 28 #include "cc/quads/stream_video_draw_quad.h" | 28 #include "cc/quads/stream_video_draw_quad.h" |
| 29 #include "cc/quads/texture_draw_quad.h" | 29 #include "cc/quads/texture_draw_quad.h" |
| 30 #include "cc/resources/layer_quad.h" | 30 #include "cc/resources/layer_quad.h" |
| 31 #include "cc/resources/priority_calculator.h" | 31 #include "cc/resources/priority_calculator.h" |
| 32 #include "cc/resources/scoped_resource.h" | 32 #include "cc/resources/scoped_resource.h" |
| 33 #include "cc/resources/sync_point_helper.h" | |
| 33 #include "cc/trees/damage_tracker.h" | 34 #include "cc/trees/damage_tracker.h" |
| 34 #include "cc/trees/proxy.h" | 35 #include "cc/trees/proxy.h" |
| 35 #include "cc/trees/single_thread_proxy.h" | 36 #include "cc/trees/single_thread_proxy.h" |
| 36 #include "gpu/GLES2/gl2extchromium.h" | 37 #include "gpu/GLES2/gl2extchromium.h" |
| 37 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h" | 38 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h" |
| 38 #include "third_party/khronos/GLES2/gl2.h" | 39 #include "third_party/khronos/GLES2/gl2.h" |
| 39 #include "third_party/khronos/GLES2/gl2ext.h" | 40 #include "third_party/khronos/GLES2/gl2ext.h" |
| 40 #include "third_party/skia/include/core/SkBitmap.h" | 41 #include "third_party/skia/include/core/SkBitmap.h" |
| 41 #include "third_party/skia/include/core/SkColor.h" | 42 #include "third_party/skia/include/core/SkColor.h" |
| 42 #include "third_party/skia/include/core/SkColorFilter.h" | 43 #include "third_party/skia/include/core/SkColorFilter.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 return false; | 81 return false; |
| 81 #endif | 82 #endif |
| 82 } | 83 } |
| 83 | 84 |
| 84 // Smallest unit that impact anti-aliasing output. We use this to | 85 // Smallest unit that impact anti-aliasing output. We use this to |
| 85 // determine when anti-aliasing is unnecessary. | 86 // determine when anti-aliasing is unnecessary. |
| 86 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; | 87 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; |
| 87 | 88 |
| 88 } // anonymous namespace | 89 } // anonymous namespace |
| 89 | 90 |
| 91 struct GLRenderer::PendingAsyncReadPixels { | |
| 92 PendingAsyncReadPixels() : sync_point(0) {} | |
| 93 | |
| 94 CopyRenderPassCallback copy_callback; | |
| 95 base::CancelableClosure finished_read_pixels_callback; | |
| 96 unsigned sync_point; | |
| 97 | |
| 98 private: | |
| 99 DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels); | |
| 100 }; | |
| 101 | |
| 90 scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, | 102 scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, |
| 91 OutputSurface* output_surface, | 103 OutputSurface* output_surface, |
| 92 ResourceProvider* resource_provider, | 104 ResourceProvider* resource_provider, |
| 93 int highp_threshold_min) { | 105 int highp_threshold_min) { |
| 94 scoped_ptr<GLRenderer> renderer(new GLRenderer( | 106 scoped_ptr<GLRenderer> renderer(new GLRenderer( |
| 95 client, output_surface, resource_provider, highp_threshold_min)); | 107 client, output_surface, resource_provider, highp_threshold_min)); |
| 96 if (!renderer->Initialize()) | 108 if (!renderer->Initialize()) |
| 97 return scoped_ptr<GLRenderer>(); | 109 return scoped_ptr<GLRenderer>(); |
| 98 | 110 |
| 99 return renderer.Pass(); | 111 return renderer.Pass(); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 | 197 |
| 186 if (!InitializeSharedObjects()) | 198 if (!InitializeSharedObjects()) |
| 187 return false; | 199 return false; |
| 188 | 200 |
| 189 // Make sure the viewport and context gets initialized, even if it is to zero. | 201 // Make sure the viewport and context gets initialized, even if it is to zero. |
| 190 ViewportChanged(); | 202 ViewportChanged(); |
| 191 return true; | 203 return true; |
| 192 } | 204 } |
| 193 | 205 |
| 194 GLRenderer::~GLRenderer() { | 206 GLRenderer::~GLRenderer() { |
| 207 while (!pending_async_read_pixels_.empty()) { | |
| 208 pending_async_read_pixels_.back()->finished_read_pixels_callback.Cancel(); | |
| 209 pending_async_read_pixels_.back()->copy_callback.Run( | |
| 210 scoped_ptr<SkBitmap>()); | |
| 211 pending_async_read_pixels_.pop_back(); | |
| 212 } | |
| 213 | |
| 195 context_->setMemoryAllocationChangedCallbackCHROMIUM(NULL); | 214 context_->setMemoryAllocationChangedCallbackCHROMIUM(NULL); |
| 196 CleanupSharedObjects(); | 215 CleanupSharedObjects(); |
| 197 } | 216 } |
| 198 | 217 |
| 199 const RendererCapabilities& GLRenderer::Capabilities() const { | 218 const RendererCapabilities& GLRenderer::Capabilities() const { |
| 200 return capabilities_; | 219 return capabilities_; |
| 201 } | 220 } |
| 202 | 221 |
| 203 WebGraphicsContext3D* GLRenderer::Context() { return context_; } | 222 WebGraphicsContext3D* GLRenderer::Context() { return context_; } |
| 204 | 223 |
| (...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1769 | 1788 |
| 1770 void GLRenderer::EnsureScissorTestDisabled() { | 1789 void GLRenderer::EnsureScissorTestDisabled() { |
| 1771 if (!is_scissor_enabled_) | 1790 if (!is_scissor_enabled_) |
| 1772 return; | 1791 return; |
| 1773 | 1792 |
| 1774 FlushTextureQuadCache(); | 1793 FlushTextureQuadCache(); |
| 1775 GLC(context_, context_->disable(GL_SCISSOR_TEST)); | 1794 GLC(context_, context_->disable(GL_SCISSOR_TEST)); |
| 1776 is_scissor_enabled_ = false; | 1795 is_scissor_enabled_ = false; |
| 1777 } | 1796 } |
| 1778 | 1797 |
| 1779 void GLRenderer::CopyCurrentRenderPassToBitmap(DrawingFrame* frame, | 1798 void GLRenderer::CopyCurrentRenderPassToBitmap( |
| 1780 SkBitmap* bitmap) { | 1799 DrawingFrame* frame, |
| 1781 gfx::Size render_pass_size = frame->current_render_pass->output_rect.size(); | 1800 const CopyRenderPassCallback& callback) { |
| 1782 bitmap->setConfig(SkBitmap::kARGB_8888_Config, | 1801 GetFramebufferPixels(frame->current_render_pass->output_rect, callback); |
| 1783 render_pass_size.width(), | |
| 1784 render_pass_size.height()); | |
| 1785 if (bitmap->allocPixels()) { | |
| 1786 bitmap->lockPixels(); | |
| 1787 GetFramebufferPixels(bitmap->getPixels(), gfx::Rect(render_pass_size)); | |
| 1788 bitmap->unlockPixels(); | |
| 1789 } | |
| 1790 } | 1802 } |
| 1791 | 1803 |
| 1792 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { | 1804 void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { |
| 1793 transform.matrix().asColMajorf(gl_matrix); | 1805 transform.matrix().asColMajorf(gl_matrix); |
| 1794 } | 1806 } |
| 1795 | 1807 |
| 1796 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) { | 1808 void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) { |
| 1797 if (quad_location == -1) | 1809 if (quad_location == -1) |
| 1798 return; | 1810 return; |
| 1799 | 1811 |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1981 | 1993 |
| 1982 void GLRenderer::EnsureBackbuffer() { | 1994 void GLRenderer::EnsureBackbuffer() { |
| 1983 if (!is_backbuffer_discarded_) | 1995 if (!is_backbuffer_discarded_) |
| 1984 return; | 1996 return; |
| 1985 | 1997 |
| 1986 output_surface_->EnsureBackbuffer(); | 1998 output_surface_->EnsureBackbuffer(); |
| 1987 is_backbuffer_discarded_ = false; | 1999 is_backbuffer_discarded_ = false; |
| 1988 } | 2000 } |
| 1989 | 2001 |
| 1990 void GLRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { | 2002 void GLRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { |
| 2003 if (!pixels || rect.IsEmpty()) | |
| 2004 return; | |
| 2005 | |
| 2006 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); | |
| 2007 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), | |
| 2008 pending_read.Pass()); | |
| 2009 | |
| 2010 // This is a syncronous call since the callback is null. | |
| 2011 DoGetFramebufferPixels(static_cast<uint8*>(pixels), | |
| 2012 rect, | |
| 2013 AsyncGetFramebufferPixelsCleanupCallback()); | |
| 2014 } | |
| 2015 | |
| 2016 void GLRenderer::GetFramebufferPixels(gfx::Rect rect, | |
| 2017 CopyRenderPassCallback callback) { | |
| 2018 if (callback.is_null()) | |
| 2019 return; | |
| 2020 if (rect.IsEmpty()) { | |
| 2021 callback.Run(scoped_ptr<SkBitmap>()); | |
| 2022 return; | |
| 2023 } | |
| 2024 | |
| 2025 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | |
| 2026 bitmap->setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); | |
| 2027 bitmap->allocPixels(); | |
| 2028 | |
| 2029 scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap)); | |
| 2030 | |
| 2031 // Save a pointer to the pixels, the bitmap is owned by the cleanup_callback. | |
| 2032 uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); | |
| 2033 | |
| 2034 AsyncGetFramebufferPixelsCleanupCallback cleanup_callback = base::Bind( | |
| 2035 &GLRenderer::PassOnSkBitmap, | |
| 2036 base::Unretained(this), | |
| 2037 base::Passed(&bitmap), | |
| 2038 base::Passed(&lock), | |
| 2039 callback); | |
| 2040 | |
| 2041 scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels); | |
| 2042 pending_read->copy_callback = callback; | |
| 2043 pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(), | |
| 2044 pending_read.Pass()); | |
| 2045 | |
| 2046 // This is an asyncronous call since the callback is not null. | |
| 2047 DoGetFramebufferPixels(pixels, rect, cleanup_callback); | |
| 2048 } | |
| 2049 | |
| 2050 void GLRenderer::DoGetFramebufferPixels( | |
| 2051 uint8* dest_pixels, | |
| 2052 gfx::Rect rect, | |
| 2053 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) { | |
| 1991 DCHECK(rect.right() <= ViewportWidth()); | 2054 DCHECK(rect.right() <= ViewportWidth()); |
| 1992 DCHECK(rect.bottom() <= ViewportHeight()); | 2055 DCHECK(rect.bottom() <= ViewportHeight()); |
| 1993 | 2056 |
| 1994 if (!pixels) | 2057 bool is_async = !cleanup_callback.is_null(); |
| 1995 return; | |
| 1996 | 2058 |
| 1997 MakeContextCurrent(); | 2059 MakeContextCurrent(); |
| 1998 | 2060 |
| 1999 bool do_workaround = NeedsIOSurfaceReadbackWorkaround(); | 2061 bool do_workaround = NeedsIOSurfaceReadbackWorkaround(); |
| 2000 | 2062 |
| 2001 GLuint temporary_texture = 0; | 2063 unsigned temporary_texture = 0; |
| 2002 GLuint temporary_fbo = 0; | 2064 unsigned temporary_fbo = 0; |
| 2003 | 2065 |
| 2004 if (do_workaround) { | 2066 if (do_workaround) { |
| 2005 // On Mac OS X, calling glReadPixels() against an FBO whose color attachment | 2067 // On Mac OS X, calling glReadPixels() against an FBO whose color attachment |
| 2006 // is an IOSurface-backed texture causes corruption of future glReadPixels() | 2068 // is an IOSurface-backed texture causes corruption of future glReadPixels() |
| 2007 // calls, even those on different OpenGL contexts. It is believed that this | 2069 // calls, even those on different OpenGL contexts. It is believed that this |
| 2008 // is the root cause of top crasher | 2070 // is the root cause of top crasher |
| 2009 // http://crbug.com/99393. <rdar://problem/10949687> | 2071 // http://crbug.com/99393. <rdar://problem/10949687> |
| 2010 | 2072 |
| 2011 temporary_texture = context_->createTexture(); | 2073 temporary_texture = context_->createTexture(); |
| 2012 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, temporary_texture)); | 2074 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, temporary_texture)); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2040 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 2102 context_->framebufferTexture2D(GL_FRAMEBUFFER, |
| 2041 GL_COLOR_ATTACHMENT0, | 2103 GL_COLOR_ATTACHMENT0, |
| 2042 GL_TEXTURE_2D, | 2104 GL_TEXTURE_2D, |
| 2043 temporary_texture, | 2105 temporary_texture, |
| 2044 0)); | 2106 0)); |
| 2045 | 2107 |
| 2046 DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) == | 2108 DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) == |
| 2047 GL_FRAMEBUFFER_COMPLETE); | 2109 GL_FRAMEBUFFER_COMPLETE); |
| 2048 } | 2110 } |
| 2049 | 2111 |
| 2050 scoped_ptr<uint8_t[]> src_pixels( | 2112 unsigned buffer = 0; |
| 2051 new uint8_t[rect.width() * rect.height() * 4]); | 2113 scoped_ptr<uint8[]> sync_pixels; |
| 2114 | |
| 2115 if (is_async) { | |
|
piman
2013/04/27 00:42:25
I think you can make your life a bit easier if:
-
danakj
2013/04/29 14:59:05
Thanks! This is what I was trying to do at first,
| |
| 2116 buffer = context_->createBuffer(); | |
| 2117 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 2118 buffer)); | |
| 2119 GLC(context_, context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 2120 4 * rect.size().GetArea(), | |
| 2121 NULL, | |
| 2122 GL_STREAM_READ)); | |
| 2123 } else { | |
| 2124 sync_pixels.reset(new uint8[4 * rect.size().GetArea()]); | |
| 2125 } | |
| 2126 | |
| 2052 GLC(context_, | 2127 GLC(context_, |
| 2053 context_->readPixels(rect.x(), | 2128 context_->readPixels(rect.x(), |
| 2054 ViewportSize().height() - rect.bottom(), | 2129 ViewportSize().height() - rect.bottom(), |
| 2055 rect.width(), | 2130 rect.width(), |
| 2056 rect.height(), | 2131 rect.height(), |
| 2057 GL_RGBA, | 2132 GL_RGBA, |
| 2058 GL_UNSIGNED_BYTE, | 2133 GL_UNSIGNED_BYTE, |
| 2059 src_pixels.get())); | 2134 sync_pixels.get())); |
| 2060 | 2135 |
| 2061 uint8_t* dest_pixels = static_cast<uint8_t*>(pixels); | 2136 if (is_async) { |
| 2062 size_t row_bytes = rect.width() * 4; | 2137 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2063 int num_rows = rect.height(); | 2138 0)); |
| 2064 size_t total_bytes = num_rows * row_bytes; | |
| 2065 for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) { | |
| 2066 // Flip Y axis. | |
| 2067 size_t src_y = total_bytes - dest_y - row_bytes; | |
| 2068 // Swizzle BGRA -> RGBA. | |
| 2069 for (size_t x = 0; x < row_bytes; x += 4) { | |
| 2070 dest_pixels[dest_y + (x + 0)] = src_pixels.get()[src_y + (x + 2)]; | |
| 2071 dest_pixels[dest_y + (x + 1)] = src_pixels.get()[src_y + (x + 1)]; | |
| 2072 dest_pixels[dest_y + (x + 2)] = src_pixels.get()[src_y + (x + 0)]; | |
| 2073 dest_pixels[dest_y + (x + 3)] = src_pixels.get()[src_y + (x + 3)]; | |
| 2074 } | |
| 2075 } | 2139 } |
| 2076 | 2140 |
| 2077 if (do_workaround) { | 2141 if (do_workaround) { |
| 2078 // Clean up. | 2142 // Clean up. |
| 2079 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); | 2143 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); |
| 2080 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); | 2144 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); |
| 2081 GLC(context_, context_->deleteFramebuffer(temporary_fbo)); | 2145 GLC(context_, context_->deleteFramebuffer(temporary_fbo)); |
| 2082 GLC(context_, context_->deleteTexture(temporary_texture)); | 2146 GLC(context_, context_->deleteTexture(temporary_texture)); |
| 2083 } | 2147 } |
| 2084 | 2148 |
| 2149 unsigned sync_point = 0; | |
| 2150 if (is_async) | |
| 2151 sync_point = context_->insertSyncPoint(); | |
| 2152 pending_async_read_pixels_.back()->sync_point = sync_point; | |
| 2153 | |
| 2154 base::Closure finished_callback = | |
| 2155 base::Bind(&GLRenderer::FinishedReadback, | |
| 2156 base::Unretained(this), | |
| 2157 cleanup_callback, | |
| 2158 buffer, | |
| 2159 base::Passed(&sync_pixels), | |
| 2160 dest_pixels, | |
| 2161 rect.size(), | |
| 2162 sync_point); | |
|
piman
2013/04/27 00:42:25
nit: Given the above, and given that you only pass
danakj
2013/04/29 14:59:05
Oh, good idea.
| |
| 2163 // Save the finished_callback so it can be cancelled. | |
| 2164 pending_async_read_pixels_.back()->finished_read_pixels_callback.Reset( | |
| 2165 finished_callback); | |
| 2166 | |
| 2167 if (is_async) { | |
| 2168 SyncPointHelper::SignalSyncPoint( | |
| 2169 context_, | |
| 2170 sync_point, | |
| 2171 finished_callback); | |
| 2172 } else { | |
| 2173 finished_callback.Run(); | |
| 2174 } | |
| 2175 | |
| 2085 EnforceMemoryPolicy(); | 2176 EnforceMemoryPolicy(); |
| 2086 } | 2177 } |
| 2087 | 2178 |
| 2179 void GLRenderer::FinishedReadback( | |
| 2180 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback, | |
| 2181 unsigned source_buffer, | |
| 2182 scoped_ptr<uint8[]> sync_pixels, | |
| 2183 uint8* dest_pixels, | |
| 2184 gfx::Size size, | |
| 2185 unsigned sync_point) { | |
| 2186 DCHECK(!pending_async_read_pixels_.empty()); | |
| 2187 DCHECK_EQ(sync_point, pending_async_read_pixels_.back()->sync_point); | |
| 2188 | |
| 2189 uint8* src_pixels = NULL; | |
| 2190 bool success = false; | |
| 2191 | |
| 2192 if (sync_pixels) { | |
| 2193 src_pixels = sync_pixels.get(); | |
| 2194 success = true; | |
| 2195 } else if (source_buffer != 0) { | |
| 2196 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 2197 source_buffer)); | |
| 2198 src_pixels = static_cast<uint8*>( | |
| 2199 context_->mapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 2200 GL_READ_ONLY)); | |
| 2201 | |
| 2202 if (src_pixels) { | |
| 2203 memcpy(dest_pixels, src_pixels, 4 * size.GetArea()); | |
| 2204 GLC(context_, context_->unmapBufferCHROMIUM( | |
| 2205 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM)); | |
| 2206 success = true; | |
| 2207 } | |
| 2208 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 2209 0)); | |
| 2210 GLC(context_, context_->deleteBuffer(source_buffer)); | |
| 2211 } | |
| 2212 | |
| 2213 if (src_pixels) { | |
| 2214 size_t row_bytes = size.width() * 4; | |
| 2215 int num_rows = size.height(); | |
| 2216 size_t total_bytes = num_rows * row_bytes; | |
| 2217 for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) { | |
| 2218 // Flip Y axis. | |
| 2219 size_t src_y = total_bytes - dest_y - row_bytes; | |
| 2220 // Swizzle BGRA -> RGBA. | |
| 2221 for (size_t x = 0; x < row_bytes; x += 4) { | |
| 2222 dest_pixels[dest_y + (x + 0)] = src_pixels[src_y + (x + 2)]; | |
| 2223 dest_pixels[dest_y + (x + 1)] = src_pixels[src_y + (x + 1)]; | |
| 2224 dest_pixels[dest_y + (x + 2)] = src_pixels[src_y + (x + 0)]; | |
| 2225 dest_pixels[dest_y + (x + 3)] = src_pixels[src_y + (x + 3)]; | |
| 2226 } | |
| 2227 } | |
| 2228 } | |
| 2229 | |
| 2230 // TODO(danakj): This can go away when synchronous readback is no more and its | |
| 2231 // contents can just move here. | |
| 2232 if (!cleanup_callback.is_null()) | |
| 2233 cleanup_callback.Run(success); | |
| 2234 | |
| 2235 pending_async_read_pixels_.pop_back(); | |
| 2236 } | |
| 2237 | |
| 2238 void GLRenderer::PassOnSkBitmap( | |
| 2239 scoped_ptr<SkBitmap> bitmap, | |
| 2240 scoped_ptr<SkAutoLockPixels> lock, | |
| 2241 const CopyRenderPassCallback& callback, | |
| 2242 bool success) { | |
| 2243 DCHECK(callback.Equals(pending_async_read_pixels_.back()->copy_callback)); | |
| 2244 | |
| 2245 lock.reset(); | |
| 2246 if (success) | |
| 2247 callback.Run(bitmap.Pass()); | |
| 2248 else | |
| 2249 callback.Run(scoped_ptr<SkBitmap>()); | |
| 2250 } | |
| 2251 | |
| 2088 bool GLRenderer::GetFramebufferTexture(ScopedResource* texture, | 2252 bool GLRenderer::GetFramebufferTexture(ScopedResource* texture, |
| 2089 gfx::Rect device_rect) { | 2253 gfx::Rect device_rect) { |
| 2090 DCHECK(!texture->id() || (texture->size() == device_rect.size() && | 2254 DCHECK(!texture->id() || (texture->size() == device_rect.size() && |
| 2091 texture->format() == GL_RGB)); | 2255 texture->format() == GL_RGB)); |
| 2092 | 2256 |
| 2093 if (!texture->id() && !texture->Allocate(device_rect.size(), | 2257 if (!texture->id() && !texture->Allocate(device_rect.size(), |
| 2094 GL_RGB, | 2258 GL_RGB, |
| 2095 ResourceProvider::TextureUsageAny)) | 2259 ResourceProvider::TextureUsageAny)) |
| 2096 return false; | 2260 return false; |
| 2097 | 2261 |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2634 resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_); | 2798 resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_); |
| 2635 | 2799 |
| 2636 ReleaseRenderPassTextures(); | 2800 ReleaseRenderPassTextures(); |
| 2637 } | 2801 } |
| 2638 | 2802 |
| 2639 bool GLRenderer::IsContextLost() { | 2803 bool GLRenderer::IsContextLost() { |
| 2640 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 2804 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
| 2641 } | 2805 } |
| 2642 | 2806 |
| 2643 } // namespace cc | 2807 } // namespace cc |
| OLD | NEW |