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

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

Issue 16831004: Perform glReadPixels with PBOs in the gpu, if PBOs are available. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed (some) comments, added new query type Created 7 years, 5 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
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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698