| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; | 289 GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; |
| 290 // Only the Skia GPU backend uses the stencil buffer. No need to clear it | 290 // Only the Skia GPU backend uses the stencil buffer. No need to clear it |
| 291 // otherwise. | 291 // otherwise. |
| 292 if (CanUseSkiaGPUBackend()) | 292 if (CanUseSkiaGPUBackend()) |
| 293 clear_bits |= GL_STENCIL_BUFFER_BIT; | 293 clear_bits |= GL_STENCIL_BUFFER_BIT; |
| 294 context_->clear(clear_bits); | 294 context_->clear(clear_bits); |
| 295 } | 295 } |
| 296 } | 296 } |
| 297 | 297 |
| 298 void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { | 298 void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { |
| 299 // FIXME: Remove this once backbuffer is automatically recreated on first use | 299 // TODO(hubbe): Remove this once backbuffer is automatically recreated |
| 300 // on first use. |
| 300 EnsureBackbuffer(); | 301 EnsureBackbuffer(); |
| 301 | 302 |
| 302 if (client_->DeviceViewport().IsEmpty()) | 303 if (client_->DeviceViewport().IsEmpty()) |
| 303 return; | 304 return; |
| 304 | 305 |
| 305 TRACE_EVENT0("cc", "GLRenderer::DrawLayers"); | 306 TRACE_EVENT0("cc", "GLRenderer::DrawLayers"); |
| 306 | 307 |
| 307 MakeContextCurrent(); | 308 MakeContextCurrent(); |
| 308 | 309 |
| 309 ReinitializeGLState(); | 310 ReinitializeGLState(); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 // quad since the destination texture has bounds matching the quad's content. | 580 // quad since the destination texture has bounds matching the quad's content. |
| 580 // 5. Draw the background texture for the contents using the same transform as | 581 // 5. Draw the background texture for the contents using the same transform as |
| 581 // used to draw the contents itself. This is done without blending to replace | 582 // used to draw the contents itself. This is done without blending to replace |
| 582 // the current background pixels with the new filtered background. | 583 // the current background pixels with the new filtered background. |
| 583 // 6. Draw the contents of the quad over drop of the new background with | 584 // 6. Draw the contents of the quad over drop of the new background with |
| 584 // blending, as per usual. The filtered background pixels will show through | 585 // blending, as per usual. The filtered background pixels will show through |
| 585 // any non-opaque pixels in this draws. | 586 // any non-opaque pixels in this draws. |
| 586 // | 587 // |
| 587 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. | 588 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. |
| 588 | 589 |
| 589 // FIXME: When this algorithm changes, update | 590 // TODO(hubbe): When this algorithm changes, update |
| 590 // LayerTreeHost::PrioritizeTextures() accordingly. | 591 // LayerTreeHost::PrioritizeTextures() accordingly. |
| 591 | 592 |
| 592 FilterOperations filters = | 593 FilterOperations filters = |
| 593 RenderSurfaceFilters::Optimize(quad->background_filters); | 594 RenderSurfaceFilters::Optimize(quad->background_filters); |
| 594 DCHECK(!filters.IsEmpty()); | 595 DCHECK(!filters.IsEmpty()); |
| 595 | 596 |
| 596 // FIXME: We only allow background filters on an opaque render surface because | 597 // TODO(hubbe): We only allow background filters on an opaque render surface |
| 597 // other surfaces may contain translucent pixels, and the contents behind | 598 // because other surfaces may contain translucent pixels, and the contents |
| 598 // those translucent pixels wouldn't have the filter applied. | 599 // behind those translucent pixels wouldn't have the filter applied. |
| 599 if (frame->current_render_pass->has_transparent_background) | 600 if (frame->current_render_pass->has_transparent_background) |
| 600 return scoped_ptr<ScopedResource>(); | 601 return scoped_ptr<ScopedResource>(); |
| 601 DCHECK(!frame->current_texture); | 602 DCHECK(!frame->current_texture); |
| 602 | 603 |
| 603 // FIXME: Do a single readback for both the surface and replica and cache the | 604 // TODO(hubbe): Do a single readback for both the surface and replica and |
| 604 // filtered results (once filter textures are not reused). | 605 // cache the filtered results (once filter textures are not reused). |
| 605 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( | 606 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( |
| 606 contents_device_transform, SharedGeometryQuad().BoundingBox())); | 607 contents_device_transform, SharedGeometryQuad().BoundingBox())); |
| 607 | 608 |
| 608 int top, right, bottom, left; | 609 int top, right, bottom, left; |
| 609 filters.GetOutsets(&top, &right, &bottom, &left); | 610 filters.GetOutsets(&top, &right, &bottom, &left); |
| 610 window_rect.Inset(-left, -top, -right, -bottom); | 611 window_rect.Inset(-left, -top, -right, -bottom); |
| 611 | 612 |
| 612 window_rect.Intersect( | 613 window_rect.Intersect( |
| 613 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); | 614 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); |
| 614 | 615 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 background_texture = DrawBackgroundFilters( | 716 background_texture = DrawBackgroundFilters( |
| 716 frame, | 717 frame, |
| 717 quad, | 718 quad, |
| 718 contents_device_transform, | 719 contents_device_transform, |
| 719 contents_device_transform_inverse); | 720 contents_device_transform_inverse); |
| 720 | 721 |
| 721 if (disable_blending) | 722 if (disable_blending) |
| 722 SetBlendEnabled(true); | 723 SetBlendEnabled(true); |
| 723 } | 724 } |
| 724 | 725 |
| 725 // FIXME: Cache this value so that we don't have to do it for both the surface | 726 // TODO(hubbe): Cache this value so that we don't have to do it for both the |
| 726 // and its replica. Apply filters to the contents texture. | 727 // surface and its replica. Apply filters to the contents texture. |
| 727 SkBitmap filter_bitmap; | 728 SkBitmap filter_bitmap; |
| 728 SkScalar color_matrix[20]; | 729 SkScalar color_matrix[20]; |
| 729 bool use_color_matrix = false; | 730 bool use_color_matrix = false; |
| 730 if (quad->filter) { | 731 if (quad->filter) { |
| 731 SkColorFilter* cf; | 732 SkColorFilter* cf; |
| 732 if ((quad->filter->asColorFilter(&cf)) && cf->asColorMatrix(color_matrix) && | 733 if ((quad->filter->asColorFilter(&cf)) && cf->asColorMatrix(color_matrix) && |
| 733 !quad->filter->getInput(0)) { | 734 !quad->filter->getInput(0)) { |
| 734 // We have a single color matrix as a filter; apply it locally | 735 // We have a single color matrix as a filter; apply it locally |
| 735 // in the compositor. | 736 // in the compositor. |
| 736 use_color_matrix = true; | 737 use_color_matrix = true; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 } | 788 } |
| 788 | 789 |
| 789 scoped_ptr<ResourceProvider::ScopedReadLockGL> mask_resource_lock; | 790 scoped_ptr<ResourceProvider::ScopedReadLockGL> mask_resource_lock; |
| 790 unsigned mask_texture_id = 0; | 791 unsigned mask_texture_id = 0; |
| 791 if (quad->mask_resource_id) { | 792 if (quad->mask_resource_id) { |
| 792 mask_resource_lock.reset(new ResourceProvider::ScopedReadLockGL( | 793 mask_resource_lock.reset(new ResourceProvider::ScopedReadLockGL( |
| 793 resource_provider_, quad->mask_resource_id)); | 794 resource_provider_, quad->mask_resource_id)); |
| 794 mask_texture_id = mask_resource_lock->texture_id(); | 795 mask_texture_id = mask_resource_lock->texture_id(); |
| 795 } | 796 } |
| 796 | 797 |
| 797 // FIXME: use the background_texture and blend the background in with this | 798 // TODO(hubbe): use the background_texture and blend the background |
| 798 // draw instead of having a separate copy of the background texture. | 799 // in with this draw instead of having a separate copy of the background |
| 800 // texture. |
| 799 | 801 |
| 800 scoped_ptr<ResourceProvider::ScopedReadLockGL> contents_resource_lock; | 802 scoped_ptr<ResourceProvider::ScopedReadLockGL> contents_resource_lock; |
| 801 if (filter_bitmap.getTexture()) { | 803 if (filter_bitmap.getTexture()) { |
| 802 GrTexture* texture = | 804 GrTexture* texture = |
| 803 reinterpret_cast<GrTexture*>(filter_bitmap.getTexture()); | 805 reinterpret_cast<GrTexture*>(filter_bitmap.getTexture()); |
| 804 Context()->bindTexture(GL_TEXTURE_2D, texture->getTextureHandle()); | 806 Context()->bindTexture(GL_TEXTURE_2D, texture->getTextureHandle()); |
| 805 } else { | 807 } else { |
| 806 contents_resource_lock = make_scoped_ptr( | 808 contents_resource_lock = make_scoped_ptr( |
| 807 new ResourceProvider::ScopedSamplerGL(resource_provider_, | 809 new ResourceProvider::ScopedSamplerGL(resource_provider_, |
| 808 contents_texture->id(), | 810 contents_texture->id(), |
| (...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 } | 2305 } |
| 2304 | 2306 |
| 2305 unsigned buffer = context_->createBuffer(); | 2307 unsigned buffer = context_->createBuffer(); |
| 2306 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 2308 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2307 buffer)); | 2309 buffer)); |
| 2308 GLC(context_, context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 2310 GLC(context_, context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2309 4 * window_rect.size().GetArea(), | 2311 4 * window_rect.size().GetArea(), |
| 2310 NULL, | 2312 NULL, |
| 2311 GL_STREAM_READ)); | 2313 GL_STREAM_READ)); |
| 2312 | 2314 |
| 2315 WebKit::WebGLId query = 0; |
| 2316 if (is_async) { |
| 2317 query = context_->createQueryEXT(); |
| 2318 GLC(context_, context_->beginQueryEXT( |
| 2319 GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, |
| 2320 query)); |
| 2321 } |
| 2322 |
| 2313 GLC(context_, | 2323 GLC(context_, |
| 2314 context_->readPixels(window_rect.x(), | 2324 context_->readPixels(window_rect.x(), |
| 2315 window_rect.y(), | 2325 window_rect.y(), |
| 2316 window_rect.width(), | 2326 window_rect.width(), |
| 2317 window_rect.height(), | 2327 window_rect.height(), |
| 2318 GL_RGBA, | 2328 GL_RGBA, |
| 2319 GL_UNSIGNED_BYTE, | 2329 GL_UNSIGNED_BYTE, |
| 2320 NULL)); | 2330 NULL)); |
| 2321 | 2331 |
| 2322 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 2332 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2323 0)); | 2333 0)); |
| 2324 | 2334 |
| 2325 if (do_workaround) { | 2335 if (do_workaround) { |
| 2326 // Clean up. | 2336 // Clean up. |
| 2327 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); | 2337 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, 0)); |
| 2328 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); | 2338 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); |
| 2329 GLC(context_, context_->deleteFramebuffer(temporary_fbo)); | 2339 GLC(context_, context_->deleteFramebuffer(temporary_fbo)); |
| 2330 GLC(context_, context_->deleteTexture(temporary_texture)); | 2340 GLC(context_, context_->deleteTexture(temporary_texture)); |
| 2331 } | 2341 } |
| 2332 | 2342 |
| 2333 base::Closure finished_callback = | 2343 base::Closure finished_callback = |
| 2334 base::Bind(&GLRenderer::FinishedReadback, | 2344 base::Bind(&GLRenderer::FinishedReadback, |
| 2335 base::Unretained(this), | 2345 base::Unretained(this), |
| 2336 cleanup_callback, | 2346 cleanup_callback, |
| 2337 buffer, | 2347 buffer, |
| 2348 query, |
| 2338 dest_pixels, | 2349 dest_pixels, |
| 2339 window_rect.size()); | 2350 window_rect.size()); |
| 2340 // Save the finished_callback so it can be cancelled. | 2351 // Save the finished_callback so it can be cancelled. |
| 2341 pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset( | 2352 pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset( |
| 2342 finished_callback); | 2353 finished_callback); |
| 2343 | 2354 |
| 2344 // Save the buffer to verify the callbacks happen in the expected order. | 2355 // Save the buffer to verify the callbacks happen in the expected order. |
| 2345 pending_async_read_pixels_.front()->buffer = buffer; | 2356 pending_async_read_pixels_.front()->buffer = buffer; |
| 2346 | 2357 |
| 2347 if (is_async) { | 2358 if (is_async) { |
| 2348 unsigned sync_point = context_->insertSyncPoint(); | 2359 GLC(context_, context_->endQueryEXT( |
| 2349 SyncPointHelper::SignalSyncPoint( | 2360 GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM)); |
| 2361 SyncPointHelper::SignalQuery( |
| 2350 context_, | 2362 context_, |
| 2351 sync_point, | 2363 query, |
| 2352 finished_callback); | 2364 finished_callback); |
| 2353 } else { | 2365 } else { |
| 2354 resource_provider_->Finish(); | 2366 resource_provider_->Finish(); |
| 2355 finished_callback.Run(); | 2367 finished_callback.Run(); |
| 2356 } | 2368 } |
| 2357 | 2369 |
| 2358 EnforceMemoryPolicy(); | 2370 EnforceMemoryPolicy(); |
| 2359 } | 2371 } |
| 2360 | 2372 |
| 2361 void GLRenderer::FinishedReadback( | 2373 void GLRenderer::FinishedReadback( |
| 2362 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback, | 2374 const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback, |
| 2363 unsigned source_buffer, | 2375 unsigned source_buffer, |
| 2376 unsigned query, |
| 2364 uint8* dest_pixels, | 2377 uint8* dest_pixels, |
| 2365 gfx::Size size) { | 2378 gfx::Size size) { |
| 2366 DCHECK(!pending_async_read_pixels_.empty()); | 2379 DCHECK(!pending_async_read_pixels_.empty()); |
| 2367 | 2380 |
| 2381 if (query != 0) { |
| 2382 GLC(context_, context_->deleteQueryEXT(query)); |
| 2383 } |
| 2384 |
| 2368 PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back(); | 2385 PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back(); |
| 2369 // Make sure we service the readbacks in order. | 2386 // Make sure we service the readbacks in order. |
| 2370 DCHECK_EQ(source_buffer, current_read->buffer); | 2387 DCHECK_EQ(source_buffer, current_read->buffer); |
| 2371 | 2388 |
| 2372 uint8* src_pixels = NULL; | 2389 uint8* src_pixels = NULL; |
| 2373 | 2390 |
| 2374 if (source_buffer != 0) { | 2391 if (source_buffer != 0) { |
| 2375 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 2392 GLC(context_, context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2376 source_buffer)); | 2393 source_buffer)); |
| 2377 src_pixels = static_cast<uint8*>( | 2394 src_pixels = static_cast<uint8*>( |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3037 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas | 3054 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas |
| 3038 // implementation. | 3055 // implementation. |
| 3039 return gr_context_ && context_->getContextAttributes().stencil; | 3056 return gr_context_ && context_->getContextAttributes().stencil; |
| 3040 } | 3057 } |
| 3041 | 3058 |
| 3042 bool GLRenderer::IsContextLost() { | 3059 bool GLRenderer::IsContextLost() { |
| 3043 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 3060 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
| 3044 } | 3061 } |
| 3045 | 3062 |
| 3046 } // namespace cc | 3063 } // namespace cc |
| OLD | NEW |