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

Side by Side Diff: cc/gl_renderer.cc

Issue 12212007: cc: Route offscreen context creation for compositor to the browser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typo Created 7 years, 10 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/gl_renderer.h" 5 #include "cc/gl_renderer.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/string_split.h" 13 #include "base/string_split.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "cc/compositor_frame.h" 16 #include "cc/compositor_frame.h"
17 #include "cc/compositor_frame_metadata.h" 17 #include "cc/compositor_frame_metadata.h"
18 #include "cc/context_provider.h"
18 #include "cc/damage_tracker.h" 19 #include "cc/damage_tracker.h"
19 #include "cc/geometry_binding.h" 20 #include "cc/geometry_binding.h"
20 #include "cc/gl_frame_data.h" 21 #include "cc/gl_frame_data.h"
21 #include "cc/layer_quad.h" 22 #include "cc/layer_quad.h"
22 #include "cc/math_util.h" 23 #include "cc/math_util.h"
23 #include "cc/priority_calculator.h" 24 #include "cc/priority_calculator.h"
24 #include "cc/proxy.h" 25 #include "cc/proxy.h"
25 #include "cc/render_pass.h" 26 #include "cc/render_pass.h"
26 #include "cc/render_surface_filters.h" 27 #include "cc/render_surface_filters.h"
27 #include "cc/scoped_resource.h" 28 #include "cc/scoped_resource.h"
28 #include "cc/single_thread_proxy.h" 29 #include "cc/single_thread_proxy.h"
29 #include "cc/stream_video_draw_quad.h" 30 #include "cc/stream_video_draw_quad.h"
30 #include "cc/texture_draw_quad.h" 31 #include "cc/texture_draw_quad.h"
31 #include "cc/video_layer_impl.h" 32 #include "cc/video_layer_impl.h"
32 #include "gpu/GLES2/gl2extchromium.h" 33 #include "gpu/GLES2/gl2extchromium.h"
33 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h" 34 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h"
34 #include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsCo ntext3D.h"
35 #include "third_party/khronos/GLES2/gl2.h" 35 #include "third_party/khronos/GLES2/gl2.h"
36 #include "third_party/khronos/GLES2/gl2ext.h" 36 #include "third_party/khronos/GLES2/gl2ext.h"
37 #include "third_party/skia/include/core/SkBitmap.h" 37 #include "third_party/skia/include/core/SkBitmap.h"
38 #include "third_party/skia/include/core/SkColor.h" 38 #include "third_party/skia/include/core/SkColor.h"
39 #include "third_party/skia/include/gpu/GrContext.h" 39 #include "third_party/skia/include/gpu/GrContext.h"
40 #include "third_party/skia/include/gpu/GrTexture.h" 40 #include "third_party/skia/include/gpu/GrTexture.h"
41 #include "third_party/skia/include/gpu/SkGpuDevice.h" 41 #include "third_party/skia/include/gpu/SkGpuDevice.h"
42 #include "third_party/skia/include/gpu/SkGrTexturePixelRef.h" 42 #include "third_party/skia/include/gpu/SkGrTexturePixelRef.h"
43 #include "ui/gfx/quad_f.h" 43 #include "ui/gfx/quad_f.h"
44 #include "ui/gfx/rect_conversions.h" 44 #include "ui/gfx/rect_conversions.h"
45 45
46 using WebKit::WebGraphicsContext3D; 46 using WebKit::WebGraphicsContext3D;
47 using WebKit::WebGraphicsMemoryAllocation; 47 using WebKit::WebGraphicsMemoryAllocation;
48 using WebKit::WebSharedGraphicsContext3D;
49 48
50 namespace cc { 49 namespace cc {
51 50
52 namespace { 51 namespace {
53 52
54 // TODO(epenner): This should probably be moved to output surface. 53 // TODO(epenner): This should probably be moved to output surface.
55 // 54 //
56 // This implements a simple fence based on client side swaps. 55 // This implements a simple fence based on client side swaps.
57 // This is to isolate the ResourceProvider from 'frames' which 56 // This is to isolate the ResourceProvider from 'frames' which
58 // it shouldn't need to care about, while still allowing us to 57 // it shouldn't need to care about, while still allowing us to
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize(); 147 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize();
149 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat(); 148 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat();
150 149
151 // The updater can access textures while the GLRenderer is using them. 150 // The updater can access textures while the GLRenderer is using them.
152 m_capabilities.allowPartialTextureUpdates = true; 151 m_capabilities.allowPartialTextureUpdates = true;
153 152
154 // Check for texture fast paths. Currently we always use MO8 textures, 153 // Check for texture fast paths. Currently we always use MO8 textures,
155 // so we only need to avoid POT textures if we have an NPOT fast-path. 154 // so we only need to avoid POT textures if we have an NPOT fast-path.
156 m_capabilities.avoidPow2Textures = extensions.count("GL_CHROMIUM_fast_NPOT_M O8_textures"); 155 m_capabilities.avoidPow2Textures = extensions.count("GL_CHROMIUM_fast_NPOT_M O8_textures");
157 156
157 m_capabilities.usingOffscreenContext3d = true;
158
158 m_isUsingBindUniform = extensions.count("GL_CHROMIUM_bind_uniform_location") ; 159 m_isUsingBindUniform = extensions.count("GL_CHROMIUM_bind_uniform_location") ;
159 160
160 // Make sure scissoring starts as disabled. 161 // Make sure scissoring starts as disabled.
161 GLC(m_context, m_context->disable(GL_SCISSOR_TEST)); 162 GLC(m_context, m_context->disable(GL_SCISSOR_TEST));
162 DCHECK(!m_isScissorEnabled); 163 DCHECK(!m_isScissorEnabled);
163 164
164 if (!initializeSharedObjects()) 165 if (!initializeSharedObjects())
165 return false; 166 return false;
166 167
167 // Make sure the viewport and context gets initialized, even if it is to zer o. 168 // Make sure the viewport and context gets initialized, even if it is to zer o.
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 float alpha = SkColorGetA(color) / 255.0; 366 float alpha = SkColorGetA(color) / 255.0;
366 367
367 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha)); 368 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha));
368 369
369 GLC(context(), context()->lineWidth(quad->width)); 370 GLC(context(), context()->lineWidth(quad->width));
370 371
371 // The indices for the line are stored in the same array as the triangle ind ices. 372 // The indices for the line are stored in the same array as the triangle ind ices.
372 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0 )); 373 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0 ));
373 } 374 }
374 375
375 static WebGraphicsContext3D* getFilterContext(bool hasImplThread) 376 static inline SkBitmap applyFilters(GLRenderer* renderer, const WebKit::WebFilte rOperations& filters, ScopedResource* sourceTextureResource)
376 {
377 if (hasImplThread)
378 return WebSharedGraphicsContext3D::compositorThreadContext();
379 else
380 return WebSharedGraphicsContext3D::mainThreadContext();
381 }
382
383 static GrContext* getFilterGrContext(bool hasImplThread)
384 {
385 if (hasImplThread)
386 return WebSharedGraphicsContext3D::compositorThreadGrContext();
387 else
388 return WebSharedGraphicsContext3D::mainThreadGrContext();
389 }
390
391 static inline SkBitmap applyFilters(GLRenderer* renderer, const WebKit::WebFilte rOperations& filters, ScopedResource* sourceTexture, bool hasImplThread)
392 { 377 {
393 if (filters.isEmpty()) 378 if (filters.isEmpty())
394 return SkBitmap(); 379 return SkBitmap();
395 380
396 WebGraphicsContext3D* filterContext = getFilterContext(hasImplThread); 381 cc::ContextProvider* offscreenContexts = renderer->resourceProvider()->offsc reenContextProvider();
397 GrContext* filterGrContext = getFilterGrContext(hasImplThread); 382 if (!offscreenContexts || !offscreenContexts->Context3d() || !offscreenConte xts->GrContext())
398
399 if (!filterContext || !filterGrContext)
400 return SkBitmap(); 383 return SkBitmap();
401 384
402 renderer->context()->flush(); 385 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eTextureResource->id());
403 386
404 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eTexture->id()); 387 // Flush the compositor context to ensure that textures there are available
405 SkBitmap source = RenderSurfaceFilters::apply(filters, lock.textureId(), sou rceTexture->size(), filterContext, filterGrContext); 388 // in the shared context. Do this after locking/creating the compositor
389 // texture.
390 renderer->resourceProvider()->flush();
391
392 // Make sure skia uses the correct GL context.
393 offscreenContexts->Context3d()->makeContextCurrent();
394
395 SkBitmap source = RenderSurfaceFilters::apply(filters, lock.textureId(), sou rceTextureResource->size(), offscreenContexts->GrContext());
396
397 // Flush skia context so that all the rendered stuff appears on the
398 // texture.
399 offscreenContexts->GrContext()->flush();
400
401 // Flush the GL context so rendering results from this context are
402 // visible in the compositor's context.
403 offscreenContexts->Context3d()->flush();
404
405 // Use the compositor's GL context again.
406 renderer->resourceProvider()->graphicsContext3D()->makeContextCurrent();
406 return source; 407 return source;
407 } 408 }
408 409
409 static SkBitmap applyImageFilter(GLRenderer* renderer, SkImageFilter* filter, Sc opedResource* sourceTexture, bool hasImplThread) 410 static SkBitmap applyImageFilter(GLRenderer* renderer, SkImageFilter* filter, Sc opedResource* sourceTextureResource)
410 { 411 {
411 if (!filter) 412 if (!filter)
412 return SkBitmap(); 413 return SkBitmap();
413 414
414 WebGraphicsContext3D* context3d = getFilterContext(hasImplThread); 415 cc::ContextProvider* offscreenContexts = renderer->resourceProvider()->offsc reenContextProvider();
415 GrContext* grContext = getFilterGrContext(hasImplThread); 416 if (!offscreenContexts || !offscreenContexts->Context3d() || !offscreenConte xts->GrContext())
416
417 if (!context3d || !grContext)
418 return SkBitmap(); 417 return SkBitmap();
419 418
420 renderer->context()->flush(); 419 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eTextureResource->id());
421 420
422 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eTexture->id()); 421 // Flush the compositor context to ensure that textures there are available
422 // in the shared context. Do this after locking/creating the compositor
423 // texture.
424 renderer->resourceProvider()->flush();
425
426 // Make sure skia uses the correct GL context.
427 offscreenContexts->Context3d()->makeContextCurrent();
423 428
424 // Wrap the source texture in a Ganesh platform texture. 429 // Wrap the source texture in a Ganesh platform texture.
425 GrBackendTextureDesc backendTextureDescription; 430 GrBackendTextureDesc backendTextureDescription;
426 backendTextureDescription.fWidth = sourceTexture->size().width(); 431 backendTextureDescription.fWidth = sourceTextureResource->size().width();
427 backendTextureDescription.fHeight = sourceTexture->size().height(); 432 backendTextureDescription.fHeight = sourceTextureResource->size().height();
428 backendTextureDescription.fConfig = kSkia8888_GrPixelConfig; 433 backendTextureDescription.fConfig = kSkia8888_GrPixelConfig;
429 backendTextureDescription.fTextureHandle = lock.textureId(); 434 backendTextureDescription.fTextureHandle = lock.textureId();
430 backendTextureDescription.fOrigin = kTopLeft_GrSurfaceOrigin; 435 backendTextureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
431 skia::RefPtr<GrTexture> texture = skia::AdoptRef(grContext->wrapBackendTextu re(backendTextureDescription)); 436 skia::RefPtr<GrTexture> texture = skia::AdoptRef(offscreenContexts->GrContex t()->wrapBackendTexture(backendTextureDescription));
432 437
433 // Place the platform texture inside an SkBitmap. 438 // Place the platform texture inside an SkBitmap.
434 SkBitmap source; 439 SkBitmap source;
435 source.setConfig(SkBitmap::kARGB_8888_Config, sourceTexture->size().width(), sourceTexture->size().height()); 440 source.setConfig(SkBitmap::kARGB_8888_Config, sourceTextureResource->size(). width(), sourceTextureResource->size().height());
436 skia::RefPtr<SkGrPixelRef> pixelRef = skia::AdoptRef(new SkGrPixelRef(textur e.get())); 441 skia::RefPtr<SkGrPixelRef> pixelRef = skia::AdoptRef(new SkGrPixelRef(textur e.get()));
437 source.setPixelRef(pixelRef.get()); 442 source.setPixelRef(pixelRef.get());
438 443
439 // Create a scratch texture for backing store. 444 // Create a scratch texture for backing store.
440 GrTextureDesc desc; 445 GrTextureDesc desc;
441 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 446 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
442 desc.fSampleCnt = 0; 447 desc.fSampleCnt = 0;
443 desc.fWidth = source.width(); 448 desc.fWidth = source.width();
444 desc.fHeight = source.height(); 449 desc.fHeight = source.height();
445 desc.fConfig = kSkia8888_GrPixelConfig; 450 desc.fConfig = kSkia8888_GrPixelConfig;
446 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 451 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
447 GrAutoScratchTexture scratchTexture(grContext, desc, GrContext::kExact_Scrat chTexMatch); 452 GrAutoScratchTexture scratchTexture(offscreenContexts->GrContext(), desc, Gr Context::kExact_ScratchTexMatch);
448 skia::RefPtr<GrTexture> backingStore = skia::AdoptRef(scratchTexture.detach( )); 453 skia::RefPtr<GrTexture> backingStore = skia::AdoptRef(scratchTexture.detach( ));
449 454
450 // Create a device and canvas using that backing store. 455 // Create a device and canvas using that backing store.
451 SkGpuDevice device(grContext, backingStore.get()); 456 SkGpuDevice device(offscreenContexts->GrContext(), backingStore.get());
452 SkCanvas canvas(&device); 457 SkCanvas canvas(&device);
453 458
454 // Draw the source bitmap through the filter to the canvas. 459 // Draw the source bitmap through the filter to the canvas.
455 SkPaint paint; 460 SkPaint paint;
456 paint.setImageFilter(filter); 461 paint.setImageFilter(filter);
457 canvas.clear(0x0); 462 canvas.clear(0x0);
458 canvas.drawSprite(source, 0, 0, &paint); 463 canvas.drawSprite(source, 0, 0, &paint);
459 canvas.flush(); 464
460 context3d->flush(); 465 // Flush skia context so that all the rendered stuff appears on the
466 // texture.
467 offscreenContexts->GrContext()->flush();
468
469 // Flush the GL context so rendering results from this context are
470 // visible in the compositor's context.
471 offscreenContexts->Context3d()->flush();
472
473 // Use the compositor's GL context again.
474 renderer->resourceProvider()->graphicsContext3D()->makeContextCurrent();
475
461 return device.accessBitmap(false); 476 return device.accessBitmap(false);
462 } 477 }
463 478
464 scoped_ptr<ScopedResource> GLRenderer::drawBackgroundFilters( 479 scoped_ptr<ScopedResource> GLRenderer::drawBackgroundFilters(
465 DrawingFrame& frame, const RenderPassDrawQuad* quad, 480 DrawingFrame& frame, const RenderPassDrawQuad* quad,
466 const gfx::Transform& contentsDeviceTransform, 481 const gfx::Transform& contentsDeviceTransform,
467 const gfx::Transform& contentsDeviceTransformInverse) 482 const gfx::Transform& contentsDeviceTransformInverse)
468 { 483 {
469 // This method draws a background filter, which applies a filter to any pixe ls behind the quad and seen through its background. 484 // This method draws a background filter, which applies a filter to any pixe ls behind the quad and seen through its background.
470 // The algorithm works as follows: 485 // The algorithm works as follows:
(...skipping 27 matching lines...) Expand all
498 int top, right, bottom, left; 513 int top, right, bottom, left;
499 filters.getOutsets(top, right, bottom, left); 514 filters.getOutsets(top, right, bottom, left);
500 deviceRect.Inset(-left, -top, -right, -bottom); 515 deviceRect.Inset(-left, -top, -right, -bottom);
501 516
502 deviceRect.Intersect(frame.currentRenderPass->output_rect); 517 deviceRect.Intersect(frame.currentRenderPass->output_rect);
503 518
504 scoped_ptr<ScopedResource> deviceBackgroundTexture = ScopedResource::create( m_resourceProvider); 519 scoped_ptr<ScopedResource> deviceBackgroundTexture = ScopedResource::create( m_resourceProvider);
505 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect)) 520 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect))
506 return scoped_ptr<ScopedResource>(); 521 return scoped_ptr<ScopedResource>();
507 522
508 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr oundTexture.get(), m_client->hasImplThread()); 523 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr oundTexture.get());
509 if (!filteredDeviceBackground.getTexture()) 524 if (!filteredDeviceBackground.getTexture())
510 return scoped_ptr<ScopedResource>(); 525 return scoped_ptr<ScopedResource>();
511 526
512 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g etTexture()); 527 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g etTexture());
513 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); 528 int filteredDeviceBackgroundTextureId = texture->getTextureHandle();
514 529
515 scoped_ptr<ScopedResource> backgroundTexture = ScopedResource::create(m_reso urceProvider); 530 scoped_ptr<ScopedResource> backgroundTexture = ScopedResource::create(m_reso urceProvider);
516 if (!backgroundTexture->Allocate(quad->rect.size(), GL_RGBA, ResourceProvide r::TextureUsageFramebuffer)) 531 if (!backgroundTexture->Allocate(quad->rect.size(), GL_RGBA, ResourceProvide r::TextureUsageFramebuffer))
517 return scoped_ptr<ScopedResource>(); 532 return scoped_ptr<ScopedResource>();
518 533
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 if (!contentsDeviceTransform.GetInverse(&contentsDeviceTransformInverse)) 566 if (!contentsDeviceTransform.GetInverse(&contentsDeviceTransformInverse))
552 return; 567 return;
553 568
554 scoped_ptr<ScopedResource> backgroundTexture = drawBackgroundFilters( 569 scoped_ptr<ScopedResource> backgroundTexture = drawBackgroundFilters(
555 frame, quad, contentsDeviceTransform, contentsDeviceTransformInverse); 570 frame, quad, contentsDeviceTransform, contentsDeviceTransformInverse);
556 571
557 // FIXME: Cache this value so that we don't have to do it for both the surfa ce and its replica. 572 // FIXME: Cache this value so that we don't have to do it for both the surfa ce and its replica.
558 // Apply filters to the contents texture. 573 // Apply filters to the contents texture.
559 SkBitmap filterBitmap; 574 SkBitmap filterBitmap;
560 if (quad->filter) { 575 if (quad->filter) {
561 filterBitmap = applyImageFilter(this, quad->filter.get(), contentsTextur e, m_client->hasImplThread()); 576 filterBitmap = applyImageFilter(this, quad->filter.get(), contentsTextur e);
562 } else { 577 } else {
563 filterBitmap = applyFilters(this, quad->filters, contentsTexture, m_clie nt->hasImplThread()); 578 filterBitmap = applyFilters(this, quad->filters, contentsTexture);
564 } 579 }
565 580
566 // Draw the background texture if there is one. 581 // Draw the background texture if there is one.
567 if (backgroundTexture) { 582 if (backgroundTexture) {
568 DCHECK(backgroundTexture->size() == quad->rect.size()); 583 DCHECK(backgroundTexture->size() == quad->rect.size());
569 ResourceProvider::ScopedReadLockGL lock(m_resourceProvider, backgroundTe xture->id()); 584 ResourceProvider::ScopedReadLockGL lock(m_resourceProvider, backgroundTe xture->id());
570 copyTextureToFramebuffer(frame, lock.textureId(), quad->rect, quad->quad Transform()); 585 copyTextureToFramebuffer(frame, lock.textureId(), quad->rect, quad->quad Transform());
571 } 586 }
572 587
573 bool clipped = false; 588 bool clipped = false;
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 1847
1833 releaseRenderPassTextures(); 1848 releaseRenderPassTextures();
1834 } 1849 }
1835 1850
1836 bool GLRenderer::isContextLost() 1851 bool GLRenderer::isContextLost()
1837 { 1852 {
1838 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); 1853 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR);
1839 } 1854 }
1840 1855
1841 } // namespace cc 1856 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698