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 <limits> | 8 #include <limits> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 << "Requested Skia GPU backend, but can't use it."; | 118 << "Requested Skia GPU backend, but can't use it."; |
119 } | 119 } |
120 | 120 |
121 return renderer.Pass(); | 121 return renderer.Pass(); |
122 } | 122 } |
123 | 123 |
124 GLRenderer::GLRenderer(RendererClient* client, | 124 GLRenderer::GLRenderer(RendererClient* client, |
125 OutputSurface* output_surface, | 125 OutputSurface* output_surface, |
126 ResourceProvider* resource_provider, | 126 ResourceProvider* resource_provider, |
127 int highp_threshold_min) | 127 int highp_threshold_min) |
128 : DirectRenderer(client, resource_provider), | 128 : DirectRenderer(client, output_surface, resource_provider), |
129 offscreen_framebuffer_id_(0), | 129 offscreen_framebuffer_id_(0), |
130 shared_geometry_quad_(gfx::RectF(-0.5f, -0.5f, 1.0f, 1.0f)), | 130 shared_geometry_quad_(gfx::RectF(-0.5f, -0.5f, 1.0f, 1.0f)), |
131 output_surface_(output_surface), | |
132 context_(output_surface->context3d()), | 131 context_(output_surface->context3d()), |
133 is_viewport_changed_(false), | |
134 is_backbuffer_discarded_(false), | 132 is_backbuffer_discarded_(false), |
135 discard_backbuffer_when_not_visible_(false), | 133 discard_backbuffer_when_not_visible_(false), |
136 is_using_bind_uniform_(false), | 134 is_using_bind_uniform_(false), |
137 visible_(true), | 135 visible_(true), |
138 is_scissor_enabled_(false), | 136 is_scissor_enabled_(false), |
139 highp_threshold_min_(highp_threshold_min), | 137 highp_threshold_min_(highp_threshold_min), |
140 highp_threshold_cache_(0), | 138 highp_threshold_cache_(0), |
141 on_demand_tile_raster_resource_id_(0) { | 139 on_demand_tile_raster_resource_id_(0) { |
142 DCHECK(context_); | 140 DCHECK(context_); |
143 } | 141 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 stats.bytesVisible = bytes_visible; | 266 stats.bytesVisible = bytes_visible; |
269 stats.bytesVisibleAndNearby = bytes_visible_and_nearby; | 267 stats.bytesVisibleAndNearby = bytes_visible_and_nearby; |
270 stats.bytesAllocated = bytes_allocated; | 268 stats.bytesAllocated = bytes_allocated; |
271 stats.backbufferRequested = !is_backbuffer_discarded_; | 269 stats.backbufferRequested = !is_backbuffer_discarded_; |
272 context_->sendManagedMemoryStatsCHROMIUM(&stats); | 270 context_->sendManagedMemoryStatsCHROMIUM(&stats); |
273 } | 271 } |
274 | 272 |
275 void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); } | 273 void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); } |
276 | 274 |
277 void GLRenderer::ViewportChanged() { | 275 void GLRenderer::ViewportChanged() { |
278 is_viewport_changed_ = true; | |
279 ReinitializeGrCanvas(); | 276 ReinitializeGrCanvas(); |
280 } | 277 } |
281 | 278 |
282 void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { | 279 void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { |
283 // On DEBUG builds, opaque render passes are cleared to blue to easily see | 280 // On DEBUG builds, opaque render passes are cleared to blue to easily see |
284 // regions that were not drawn on the screen. | 281 // regions that were not drawn on the screen. |
285 if (frame->current_render_pass->has_transparent_background) | 282 if (frame->current_render_pass->has_transparent_background) |
286 GLC(context_, context_->clearColor(0, 0, 0, 0)); | 283 GLC(context_, context_->clearColor(0, 0, 0, 0)); |
287 else | 284 else |
288 GLC(context_, context_->clearColor(0, 0, 1, 1)); | 285 GLC(context_, context_->clearColor(0, 0, 1, 1)); |
289 | 286 |
290 bool always_clear = false; | 287 bool always_clear = false; |
291 #ifndef NDEBUG | 288 #ifndef NDEBUG |
292 always_clear = true; | 289 always_clear = true; |
293 #endif | 290 #endif |
294 if (always_clear || frame->current_render_pass->has_transparent_background) { | 291 if (always_clear || frame->current_render_pass->has_transparent_background) { |
295 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; | 292 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; |
296 // Only the Skia GPU backend uses the stencil buffer. No need to clear it | 293 // Only the Skia GPU backend uses the stencil buffer. No need to clear it |
297 // otherwise. | 294 // otherwise. |
298 if (CanUseSkiaGPUBackend()) | 295 if (CanUseSkiaGPUBackend()) |
299 clear_bits |= GL_STENCIL_BUFFER_BIT; | 296 clear_bits |= GL_STENCIL_BUFFER_BIT; |
300 context_->clear(clear_bits); | 297 context_->clear(clear_bits); |
301 } | 298 } |
302 } | 299 } |
303 | 300 |
304 void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { | 301 void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { |
305 // FIXME: Remove this once backbuffer is automatically recreated on first use | 302 // FIXME: Remove this once backbuffer is automatically recreated on first use |
306 EnsureBackbuffer(); | 303 EnsureBackbuffer(); |
307 | 304 |
308 if (ViewportSize().IsEmpty()) | 305 if (client_->DeviceViewport().IsEmpty()) |
309 return; | 306 return; |
310 | 307 |
311 TRACE_EVENT0("cc", "GLRenderer::DrawLayers"); | 308 TRACE_EVENT0("cc", "GLRenderer::DrawLayers"); |
312 if (is_viewport_changed_) { | |
313 // Only reshape when we know we are going to draw. Otherwise, the reshape | |
314 // can leave the window at the wrong size if we never draw and the proper | |
315 // viewport size is never set. | |
316 is_viewport_changed_ = false; | |
317 output_surface_->Reshape(gfx::Size(ViewportWidth(), ViewportHeight()), | |
318 DeviceScaleFactor()); | |
319 } | |
320 | 309 |
321 MakeContextCurrent(); | 310 MakeContextCurrent(); |
322 | 311 |
323 ReinitializeGLState(); | 312 ReinitializeGLState(); |
324 } | 313 } |
325 | 314 |
326 void GLRenderer::DoNoOp() { | 315 void GLRenderer::DoNoOp() { |
327 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); | 316 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); |
328 GLC(context_, context_->flush()); | 317 GLC(context_, context_->flush()); |
329 } | 318 } |
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 // Reset the canvas matrix to identity because the clip rect is in target | 1485 // Reset the canvas matrix to identity because the clip rect is in target |
1497 // space. | 1486 // space. |
1498 SkMatrix sk_identity; | 1487 SkMatrix sk_identity; |
1499 sk_identity.setIdentity(); | 1488 sk_identity.setIdentity(); |
1500 sk_canvas_->setMatrix(sk_identity); | 1489 sk_canvas_->setMatrix(sk_identity); |
1501 | 1490 |
1502 if (is_scissor_enabled_) { | 1491 if (is_scissor_enabled_) { |
1503 sk_canvas_->clipRect(gfx::RectToSkRect(scissor_rect_), | 1492 sk_canvas_->clipRect(gfx::RectToSkRect(scissor_rect_), |
1504 SkRegion::kReplace_Op); | 1493 SkRegion::kReplace_Op); |
1505 } else { | 1494 } else { |
1506 sk_canvas_->clipRect(gfx::RectToSkRect(gfx::Rect(ViewportSize())), | 1495 sk_canvas_->clipRect(gfx::RectToSkRect(client_->DeviceViewport()), |
1507 SkRegion::kReplace_Op); | 1496 SkRegion::kReplace_Op); |
1508 } | 1497 } |
1509 | 1498 |
1510 gfx::Transform contents_device_transform = frame->window_matrix * | 1499 gfx::Transform contents_device_transform = frame->window_matrix * |
1511 frame->projection_matrix * quad->quadTransform(); | 1500 frame->projection_matrix * quad->quadTransform(); |
1512 contents_device_transform.Translate(quad->rect.x(), | 1501 contents_device_transform.Translate(quad->rect.x(), |
1513 quad->rect.y()); | 1502 quad->rect.y()); |
1514 contents_device_transform.FlattenTo2d(); | 1503 contents_device_transform.FlattenTo2d(); |
1515 SkMatrix sk_device_matrix; | 1504 SkMatrix sk_device_matrix; |
1516 gfx::TransformToFlattenedSkMatrix(contents_device_transform, | 1505 gfx::TransformToFlattenedSkMatrix(contents_device_transform, |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 void GLRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) { | 1952 void GLRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) { |
1964 DCHECK(visible_); | 1953 DCHECK(visible_); |
1965 DCHECK(!is_backbuffer_discarded_); | 1954 DCHECK(!is_backbuffer_discarded_); |
1966 | 1955 |
1967 TRACE_EVENT0("cc", "GLRenderer::SwapBuffers"); | 1956 TRACE_EVENT0("cc", "GLRenderer::SwapBuffers"); |
1968 // We're done! Time to swapbuffers! | 1957 // We're done! Time to swapbuffers! |
1969 | 1958 |
1970 if (capabilities_.using_partial_swap && client_->AllowPartialSwap()) { | 1959 if (capabilities_.using_partial_swap && client_->AllowPartialSwap()) { |
1971 // If supported, we can save significant bandwidth by only swapping the | 1960 // If supported, we can save significant bandwidth by only swapping the |
1972 // damaged/scissored region (clamped to the viewport) | 1961 // damaged/scissored region (clamped to the viewport) |
1973 swap_buffer_rect_.Intersect(gfx::Rect(ViewportSize())); | 1962 swap_buffer_rect_.Intersect(client_->DeviceViewport()); |
1974 int flipped_y_pos_of_rect_bottom = | 1963 int flipped_y_pos_of_rect_bottom = |
1975 ViewportHeight() - swap_buffer_rect_.y() - swap_buffer_rect_.height(); | 1964 client_->DeviceViewport().height() - swap_buffer_rect_.y() - |
| 1965 swap_buffer_rect_.height(); |
1976 output_surface_->PostSubBuffer(gfx::Rect(swap_buffer_rect_.x(), | 1966 output_surface_->PostSubBuffer(gfx::Rect(swap_buffer_rect_.x(), |
1977 flipped_y_pos_of_rect_bottom, | 1967 flipped_y_pos_of_rect_bottom, |
1978 swap_buffer_rect_.width(), | 1968 swap_buffer_rect_.width(), |
1979 swap_buffer_rect_.height()), | 1969 swap_buffer_rect_.height()), |
1980 latency_info); | 1970 latency_info); |
1981 } else { | 1971 } else { |
1982 output_surface_->SwapBuffers(latency_info); | 1972 output_surface_->SwapBuffers(latency_info); |
1983 } | 1973 } |
1984 | 1974 |
1985 swap_buffer_rect_ = gfx::Rect(); | 1975 swap_buffer_rect_ = gfx::Rect(); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2119 | 2109 |
2120 // This is an asyncronous call since the callback is not null. | 2110 // This is an asyncronous call since the callback is not null. |
2121 DoGetFramebufferPixels(pixels, rect, flipped_y, cleanup_callback); | 2111 DoGetFramebufferPixels(pixels, rect, flipped_y, cleanup_callback); |
2122 } | 2112 } |
2123 | 2113 |
2124 void GLRenderer::DoGetFramebufferPixels( | 2114 void GLRenderer::DoGetFramebufferPixels( |
2125 uint8* dest_pixels, | 2115 uint8* dest_pixels, |
2126 gfx::Rect rect, | 2116 gfx::Rect rect, |
2127 bool flipped_y, | 2117 bool flipped_y, |
2128 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) { | 2118 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) { |
2129 DCHECK(rect.right() <= ViewportWidth()); | 2119 DCHECK(rect.right() <= client_->DeviceViewport().width()); |
2130 DCHECK(rect.bottom() <= ViewportHeight()); | 2120 DCHECK(rect.bottom() <= client_->DeviceViewport().height()); |
2131 | 2121 |
2132 bool is_async = !cleanup_callback.is_null(); | 2122 bool is_async = !cleanup_callback.is_null(); |
2133 | 2123 |
2134 MakeContextCurrent(); | 2124 MakeContextCurrent(); |
2135 | 2125 |
2136 bool do_workaround = NeedsIOSurfaceReadbackWorkaround(); | 2126 bool do_workaround = NeedsIOSurfaceReadbackWorkaround(); |
2137 | 2127 |
2138 unsigned temporary_texture = 0; | 2128 unsigned temporary_texture = 0; |
2139 unsigned temporary_fbo = 0; | 2129 unsigned temporary_fbo = 0; |
2140 | 2130 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2359 make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL( | 2349 make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL( |
2360 resource_provider_, texture->id())); | 2350 resource_provider_, texture->id())); |
2361 unsigned texture_id = current_framebuffer_lock_->texture_id(); | 2351 unsigned texture_id = current_framebuffer_lock_->texture_id(); |
2362 GLC(context_, | 2352 GLC(context_, |
2363 context_->framebufferTexture2D( | 2353 context_->framebufferTexture2D( |
2364 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0)); | 2354 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0)); |
2365 | 2355 |
2366 DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) == | 2356 DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) == |
2367 GL_FRAMEBUFFER_COMPLETE || IsContextLost()); | 2357 GL_FRAMEBUFFER_COMPLETE || IsContextLost()); |
2368 | 2358 |
2369 InitializeMatrices(frame, framebuffer_rect, false); | 2359 InitializeMatrices( |
2370 SetDrawViewportSize(framebuffer_rect.size()); | 2360 frame, framebuffer_rect, gfx::Rect(framebuffer_rect.size()), false); |
| 2361 SetDrawViewport(gfx::Rect(framebuffer_rect.size())); |
2371 | 2362 |
2372 return true; | 2363 return true; |
2373 } | 2364 } |
2374 | 2365 |
2375 void GLRenderer::SetScissorTestRect(gfx::Rect scissor_rect) { | 2366 void GLRenderer::SetScissorTestRect(gfx::Rect scissor_rect) { |
2376 EnsureScissorTestEnabled(); | 2367 EnsureScissorTestEnabled(); |
2377 | 2368 |
2378 // Don't unnecessarily ask the context to change the scissor, because it | 2369 // Don't unnecessarily ask the context to change the scissor, because it |
2379 // may cause undesired GPU pipeline flushes. | 2370 // may cause undesired GPU pipeline flushes. |
2380 if (scissor_rect == scissor_rect_) | 2371 if (scissor_rect == scissor_rect_) |
2381 return; | 2372 return; |
2382 | 2373 |
2383 scissor_rect_ = scissor_rect; | 2374 scissor_rect_ = scissor_rect; |
2384 FlushTextureQuadCache(); | 2375 FlushTextureQuadCache(); |
2385 GLC(context_, | 2376 GLC(context_, |
2386 context_->scissor(scissor_rect.x(), | 2377 context_->scissor(scissor_rect.x(), |
2387 scissor_rect.y(), | 2378 scissor_rect.y(), |
2388 scissor_rect.width(), | 2379 scissor_rect.width(), |
2389 scissor_rect.height())); | 2380 scissor_rect.height())); |
2390 } | 2381 } |
2391 | 2382 |
2392 void GLRenderer::SetDrawViewportSize(gfx::Size viewport_size) { | 2383 void GLRenderer::SetDrawViewport(gfx::Rect viewport) { |
2393 current_framebuffer_size_ = viewport_size; | 2384 current_framebuffer_size_ = viewport.size(); |
2394 GLC(context_, | 2385 GLC(context_, context_->viewport(viewport.x(), |
2395 context_->viewport(0, 0, viewport_size.width(), viewport_size.height())); | 2386 viewport.y(), |
| 2387 viewport.width(), |
| 2388 viewport.height())); |
2396 } | 2389 } |
2397 | 2390 |
2398 bool GLRenderer::MakeContextCurrent() { return context_->makeContextCurrent(); } | 2391 bool GLRenderer::MakeContextCurrent() { return context_->makeContextCurrent(); } |
2399 | 2392 |
2400 bool GLRenderer::InitializeSharedObjects() { | 2393 bool GLRenderer::InitializeSharedObjects() { |
2401 TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects"); | 2394 TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects"); |
2402 MakeContextCurrent(); | 2395 MakeContextCurrent(); |
2403 | 2396 |
2404 // Create an FBO for doing offscreen rendering. | 2397 // Create an FBO for doing offscreen rendering. |
2405 GLC(context_, offscreen_framebuffer_id_ = context_->createFramebuffer()); | 2398 GLC(context_, offscreen_framebuffer_id_ = context_->createFramebuffer()); |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2859 resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_); | 2852 resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_); |
2860 | 2853 |
2861 ReleaseRenderPassTextures(); | 2854 ReleaseRenderPassTextures(); |
2862 } | 2855 } |
2863 | 2856 |
2864 void GLRenderer::ReinitializeGrCanvas() { | 2857 void GLRenderer::ReinitializeGrCanvas() { |
2865 if (!CanUseSkiaGPUBackend()) | 2858 if (!CanUseSkiaGPUBackend()) |
2866 return; | 2859 return; |
2867 | 2860 |
2868 GrBackendRenderTargetDesc desc; | 2861 GrBackendRenderTargetDesc desc; |
2869 desc.fWidth = ViewportWidth(); | 2862 desc.fWidth = client_->DeviceViewport().width(); |
2870 desc.fHeight = ViewportHeight(); | 2863 desc.fHeight = client_->DeviceViewport().height(); |
2871 desc.fConfig = kRGBA_8888_GrPixelConfig; | 2864 desc.fConfig = kRGBA_8888_GrPixelConfig; |
2872 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 2865 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
2873 desc.fSampleCnt = 1; | 2866 desc.fSampleCnt = 1; |
2874 desc.fStencilBits = 8; | 2867 desc.fStencilBits = 8; |
2875 desc.fRenderTargetHandle = 0; | 2868 desc.fRenderTargetHandle = 0; |
2876 | 2869 |
2877 skia::RefPtr<GrSurface> surface( | 2870 skia::RefPtr<GrSurface> surface( |
2878 skia::AdoptRef(gr_context_->wrapBackendRenderTarget(desc))); | 2871 skia::AdoptRef(gr_context_->wrapBackendRenderTarget(desc))); |
2879 skia::RefPtr<SkDevice> device( | 2872 skia::RefPtr<SkDevice> device( |
2880 skia::AdoptRef(SkGpuDevice::Create(surface.get()))); | 2873 skia::AdoptRef(SkGpuDevice::Create(surface.get()))); |
(...skipping 23 matching lines...) Expand all Loading... |
2904 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas | 2897 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas |
2905 // implementation. | 2898 // implementation. |
2906 return gr_context_ && context_->getContextAttributes().stencil; | 2899 return gr_context_ && context_->getContextAttributes().stencil; |
2907 } | 2900 } |
2908 | 2901 |
2909 bool GLRenderer::IsContextLost() { | 2902 bool GLRenderer::IsContextLost() { |
2910 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 2903 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
2911 } | 2904 } |
2912 | 2905 |
2913 } // namespace cc | 2906 } // namespace cc |
OLD | NEW |