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/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/damage_tracker.h" | 18 #include "cc/damage_tracker.h" |
19 #include "cc/ganesh_context_provider.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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 m_capabilities.usingDiscardBackbuffer = extensions.count("GL_CHROMIUM_discar d_backbuffer"); | 142 m_capabilities.usingDiscardBackbuffer = extensions.count("GL_CHROMIUM_discar d_backbuffer"); |
144 | 143 |
145 m_capabilities.usingEglImage = extensions.count("GL_OES_EGL_image_external") ; | 144 m_capabilities.usingEglImage = extensions.count("GL_OES_EGL_image_external") ; |
146 | 145 |
147 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize(); | 146 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize(); |
148 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat(); | 147 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat(); |
149 | 148 |
150 // The updater can access textures while the GLRenderer is using them. | 149 // The updater can access textures while the GLRenderer is using them. |
151 m_capabilities.allowPartialTextureUpdates = true; | 150 m_capabilities.allowPartialTextureUpdates = true; |
152 | 151 |
152 m_capabilities.usingOffscreenContext3d = true; | |
153 | |
153 m_isUsingBindUniform = extensions.count("GL_CHROMIUM_bind_uniform_location") ; | 154 m_isUsingBindUniform = extensions.count("GL_CHROMIUM_bind_uniform_location") ; |
154 | 155 |
155 // Make sure scissoring starts as disabled. | 156 // Make sure scissoring starts as disabled. |
156 GLC(m_context, m_context->disable(GL_SCISSOR_TEST)); | 157 GLC(m_context, m_context->disable(GL_SCISSOR_TEST)); |
157 DCHECK(!m_isScissorEnabled); | 158 DCHECK(!m_isScissorEnabled); |
158 | 159 |
159 if (!initializeSharedObjects()) | 160 if (!initializeSharedObjects()) |
160 return false; | 161 return false; |
161 | 162 |
162 // Make sure the viewport and context gets initialized, even if it is to zer o. | 163 // 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 Loading... | |
360 float alpha = SkColorGetA(color) / 255.0; | 361 float alpha = SkColorGetA(color) / 255.0; |
361 | 362 |
362 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha)); | 363 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha)); |
363 | 364 |
364 GLC(context(), context()->lineWidth(quad->width)); | 365 GLC(context(), context()->lineWidth(quad->width)); |
365 | 366 |
366 // The indices for the line are stored in the same array as the triangle ind ices. | 367 // The indices for the line are stored in the same array as the triangle ind ices. |
367 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0 )); | 368 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0 )); |
368 } | 369 } |
369 | 370 |
370 static WebGraphicsContext3D* getFilterContext(bool hasImplThread) | 371 static inline SkBitmap applyFilters(GLRenderer* renderer, const WebKit::WebFilte rOperations& filters, ScopedResource* sourceResource) |
371 { | |
372 if (hasImplThread) | |
373 return WebSharedGraphicsContext3D::compositorThreadContext(); | |
374 else | |
375 return WebSharedGraphicsContext3D::mainThreadContext(); | |
376 } | |
377 | |
378 static GrContext* getFilterGrContext(bool hasImplThread) | |
379 { | |
380 if (hasImplThread) | |
381 return WebSharedGraphicsContext3D::compositorThreadGrContext(); | |
382 else | |
383 return WebSharedGraphicsContext3D::mainThreadGrContext(); | |
384 } | |
385 | |
386 static inline SkBitmap applyFilters(GLRenderer* renderer, const WebKit::WebFilte rOperations& filters, ScopedResource* sourceTexture, bool hasImplThread) | |
387 { | 372 { |
388 if (filters.isEmpty()) | 373 if (filters.isEmpty()) |
389 return SkBitmap(); | 374 return SkBitmap(); |
390 | 375 |
391 WebGraphicsContext3D* filterContext = getFilterContext(hasImplThread); | 376 if (!renderer->resourceProvider()->ganeshContextProvider()->has_contexts()) |
Stephen White
2013/02/11 19:48:23
Nit: Skia doesn't actually refer to "Ganesh" anyw
danakj
2013/02/11 21:06:13
Ya ok, I think that sounds fine.
Stephen White
2013/02/11 21:12:06
Actually, maybe if it provides both the GrContext
danakj
2013/02/11 21:14:21
Well, it's the SharedOffscreenContextProvider. I c
Stephen White
2013/02/11 21:17:49
Hmm.. just contextProvider() doesn't cut it, I gue
| |
392 GrContext* filterGrContext = getFilterGrContext(hasImplThread); | |
393 | |
394 if (!filterContext || !filterGrContext) | |
395 return SkBitmap(); | 377 return SkBitmap(); |
396 | 378 |
397 renderer->context()->flush(); | 379 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eResource->id()); |
398 | 380 GaneshContextProvider::ScopedContextsFlushed ganeshContexts(renderer->resour ceProvider(), renderer->resourceProvider()->ganeshContextProvider()); |
399 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eTexture->id()); | 381 SkBitmap source = RenderSurfaceFilters::apply(filters, lock.textureId(), sou rceResource->size(), ganeshContexts.gr_context()); |
400 SkBitmap source = RenderSurfaceFilters::apply(filters, lock.textureId(), sou rceTexture->size(), filterContext, filterGrContext); | |
401 return source; | 382 return source; |
402 } | 383 } |
403 | 384 |
404 static SkBitmap applyImageFilter(GLRenderer* renderer, SkImageFilter* filter, Sc opedResource* sourceTexture, bool hasImplThread) | 385 static SkBitmap applyImageFilter(GLRenderer* renderer, SkImageFilter* filter, Sc opedResource* sourceResource) |
405 { | 386 { |
406 if (!filter) | 387 if (!filter) |
407 return SkBitmap(); | 388 return SkBitmap(); |
408 | 389 |
409 WebGraphicsContext3D* context3d = getFilterContext(hasImplThread); | 390 if (!renderer->resourceProvider()->ganeshContextProvider()->has_contexts()) |
410 GrContext* grContext = getFilterGrContext(hasImplThread); | |
411 | |
412 if (!context3d || !grContext) | |
413 return SkBitmap(); | 391 return SkBitmap(); |
414 | 392 |
415 renderer->context()->flush(); | 393 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eResource->id()); |
416 | 394 |
417 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc eTexture->id()); | 395 // Flush after locking the resource on the compositor context. |
396 GaneshContextProvider::ScopedContextsFlushed ganeshContexts(renderer->resour ceProvider(), renderer->resourceProvider()->ganeshContextProvider()); | |
418 | 397 |
419 // Wrap the source texture in a Ganesh platform texture. | 398 // Wrap the source texture in a Ganesh platform texture. |
420 GrBackendTextureDesc backendTextureDescription; | 399 GrBackendTextureDesc backendTextureDescription; |
421 backendTextureDescription.fWidth = sourceTexture->size().width(); | 400 backendTextureDescription.fWidth = sourceResource->size().width(); |
422 backendTextureDescription.fHeight = sourceTexture->size().height(); | 401 backendTextureDescription.fHeight = sourceResource->size().height(); |
Stephen White
2013/02/11 19:48:23
Nit: Is this sourceResource not always a texture?
danakj
2013/02/11 21:06:13
Ya it will be a texture, I was confused because it
Stephen White
2013/02/11 21:12:06
Sure, that's fine.
| |
423 backendTextureDescription.fConfig = kSkia8888_GrPixelConfig; | 402 backendTextureDescription.fConfig = kSkia8888_GrPixelConfig; |
424 backendTextureDescription.fTextureHandle = lock.textureId(); | 403 backendTextureDescription.fTextureHandle = lock.textureId(); |
425 backendTextureDescription.fOrigin = kTopLeft_GrSurfaceOrigin; | 404 backendTextureDescription.fOrigin = kTopLeft_GrSurfaceOrigin; |
426 skia::RefPtr<GrTexture> texture = skia::AdoptRef(grContext->wrapBackendTextu re(backendTextureDescription)); | 405 skia::RefPtr<GrTexture> texture = skia::AdoptRef(ganeshContexts.gr_context() ->wrapBackendTexture(backendTextureDescription)); |
427 | 406 |
428 // Place the platform texture inside an SkBitmap. | 407 // Place the platform texture inside an SkBitmap. |
429 SkBitmap source; | 408 SkBitmap source; |
430 source.setConfig(SkBitmap::kARGB_8888_Config, sourceTexture->size().width(), sourceTexture->size().height()); | 409 source.setConfig(SkBitmap::kARGB_8888_Config, sourceResource->size().width() , sourceResource->size().height()); |
431 skia::RefPtr<SkGrPixelRef> pixelRef = skia::AdoptRef(new SkGrPixelRef(textur e.get())); | 410 skia::RefPtr<SkGrPixelRef> pixelRef = skia::AdoptRef(new SkGrPixelRef(textur e.get())); |
432 source.setPixelRef(pixelRef.get()); | 411 source.setPixelRef(pixelRef.get()); |
433 | 412 |
434 // Create a scratch texture for backing store. | 413 // Create a scratch texture for backing store. |
435 GrTextureDesc desc; | 414 GrTextureDesc desc; |
436 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | 415 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
437 desc.fSampleCnt = 0; | 416 desc.fSampleCnt = 0; |
438 desc.fWidth = source.width(); | 417 desc.fWidth = source.width(); |
439 desc.fHeight = source.height(); | 418 desc.fHeight = source.height(); |
440 desc.fConfig = kSkia8888_GrPixelConfig; | 419 desc.fConfig = kSkia8888_GrPixelConfig; |
441 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 420 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
442 GrAutoScratchTexture scratchTexture(grContext, desc, GrContext::kExact_Scrat chTexMatch); | 421 GrAutoScratchTexture scratchTexture(ganeshContexts.gr_context(), desc, GrCon text::kExact_ScratchTexMatch); |
443 skia::RefPtr<GrTexture> backingStore = skia::AdoptRef(scratchTexture.detach( )); | 422 skia::RefPtr<GrTexture> backingStore = skia::AdoptRef(scratchTexture.detach( )); |
444 | 423 |
445 // Create a device and canvas using that backing store. | 424 // Create a device and canvas using that backing store. |
446 SkGpuDevice device(grContext, backingStore.get()); | 425 SkGpuDevice device(ganeshContexts.gr_context(), backingStore.get()); |
447 SkCanvas canvas(&device); | 426 SkCanvas canvas(&device); |
448 | 427 |
449 // Draw the source bitmap through the filter to the canvas. | 428 // Draw the source bitmap through the filter to the canvas. |
450 SkPaint paint; | 429 SkPaint paint; |
451 paint.setImageFilter(filter); | 430 paint.setImageFilter(filter); |
452 canvas.clear(0x0); | 431 canvas.clear(0x0); |
453 canvas.drawSprite(source, 0, 0, &paint); | 432 canvas.drawSprite(source, 0, 0, &paint); |
454 canvas.flush(); | |
455 context3d->flush(); | |
Stephen White
2013/02/11 19:48:23
I still don't think it's a good idea to make this
| |
456 return device.accessBitmap(false); | 433 return device.accessBitmap(false); |
457 } | 434 } |
458 | 435 |
459 scoped_ptr<ScopedResource> GLRenderer::drawBackgroundFilters( | 436 scoped_ptr<ScopedResource> GLRenderer::drawBackgroundFilters( |
460 DrawingFrame& frame, const RenderPassDrawQuad* quad, | 437 DrawingFrame& frame, const RenderPassDrawQuad* quad, |
461 const gfx::Transform& contentsDeviceTransform, | 438 const gfx::Transform& contentsDeviceTransform, |
462 const gfx::Transform& contentsDeviceTransformInverse) | 439 const gfx::Transform& contentsDeviceTransformInverse) |
463 { | 440 { |
464 // This method draws a background filter, which applies a filter to any pixe ls behind the quad and seen through its background. | 441 // This method draws a background filter, which applies a filter to any pixe ls behind the quad and seen through its background. |
465 // The algorithm works as follows: | 442 // The algorithm works as follows: |
(...skipping 27 matching lines...) Expand all Loading... | |
493 int top, right, bottom, left; | 470 int top, right, bottom, left; |
494 filters.getOutsets(top, right, bottom, left); | 471 filters.getOutsets(top, right, bottom, left); |
495 deviceRect.Inset(-left, -top, -right, -bottom); | 472 deviceRect.Inset(-left, -top, -right, -bottom); |
496 | 473 |
497 deviceRect.Intersect(frame.currentRenderPass->output_rect); | 474 deviceRect.Intersect(frame.currentRenderPass->output_rect); |
498 | 475 |
499 scoped_ptr<ScopedResource> deviceBackgroundTexture = ScopedResource::create( m_resourceProvider); | 476 scoped_ptr<ScopedResource> deviceBackgroundTexture = ScopedResource::create( m_resourceProvider); |
500 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect)) | 477 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect)) |
501 return scoped_ptr<ScopedResource>(); | 478 return scoped_ptr<ScopedResource>(); |
502 | 479 |
503 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr oundTexture.get(), m_client->hasImplThread()); | 480 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr oundTexture.get()); |
504 if (!filteredDeviceBackground.getTexture()) | 481 if (!filteredDeviceBackground.getTexture()) |
505 return scoped_ptr<ScopedResource>(); | 482 return scoped_ptr<ScopedResource>(); |
506 | 483 |
507 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g etTexture()); | 484 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g etTexture()); |
508 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); | 485 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); |
509 | 486 |
510 scoped_ptr<ScopedResource> backgroundTexture = ScopedResource::create(m_reso urceProvider); | 487 scoped_ptr<ScopedResource> backgroundTexture = ScopedResource::create(m_reso urceProvider); |
511 if (!backgroundTexture->Allocate(quad->rect.size(), GL_RGBA, ResourceProvide r::TextureUsageFramebuffer)) | 488 if (!backgroundTexture->Allocate(quad->rect.size(), GL_RGBA, ResourceProvide r::TextureUsageFramebuffer)) |
512 return scoped_ptr<ScopedResource>(); | 489 return scoped_ptr<ScopedResource>(); |
513 | 490 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 if (!contentsDeviceTransform.GetInverse(&contentsDeviceTransformInverse)) | 523 if (!contentsDeviceTransform.GetInverse(&contentsDeviceTransformInverse)) |
547 return; | 524 return; |
548 | 525 |
549 scoped_ptr<ScopedResource> backgroundTexture = drawBackgroundFilters( | 526 scoped_ptr<ScopedResource> backgroundTexture = drawBackgroundFilters( |
550 frame, quad, contentsDeviceTransform, contentsDeviceTransformInverse); | 527 frame, quad, contentsDeviceTransform, contentsDeviceTransformInverse); |
551 | 528 |
552 // FIXME: Cache this value so that we don't have to do it for both the surfa ce and its replica. | 529 // FIXME: Cache this value so that we don't have to do it for both the surfa ce and its replica. |
553 // Apply filters to the contents texture. | 530 // Apply filters to the contents texture. |
554 SkBitmap filterBitmap; | 531 SkBitmap filterBitmap; |
555 if (quad->filter) { | 532 if (quad->filter) { |
556 filterBitmap = applyImageFilter(this, quad->filter.get(), contentsTextur e, m_client->hasImplThread()); | 533 filterBitmap = applyImageFilter(this, quad->filter.get(), contentsTextur e); |
557 } else { | 534 } else { |
558 filterBitmap = applyFilters(this, quad->filters, contentsTexture, m_clie nt->hasImplThread()); | 535 filterBitmap = applyFilters(this, quad->filters, contentsTexture); |
559 } | 536 } |
560 | 537 |
561 // Draw the background texture if there is one. | 538 // Draw the background texture if there is one. |
562 if (backgroundTexture) { | 539 if (backgroundTexture) { |
563 DCHECK(backgroundTexture->size() == quad->rect.size()); | 540 DCHECK(backgroundTexture->size() == quad->rect.size()); |
564 ResourceProvider::ScopedReadLockGL lock(m_resourceProvider, backgroundTe xture->id()); | 541 ResourceProvider::ScopedReadLockGL lock(m_resourceProvider, backgroundTe xture->id()); |
565 copyTextureToFramebuffer(frame, lock.textureId(), quad->rect, quad->quad Transform()); | 542 copyTextureToFramebuffer(frame, lock.textureId(), quad->rect, quad->quad Transform()); |
566 } | 543 } |
567 | 544 |
568 bool clipped = false; | 545 bool clipped = false; |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1813 | 1790 |
1814 releaseRenderPassTextures(); | 1791 releaseRenderPassTextures(); |
1815 } | 1792 } |
1816 | 1793 |
1817 bool GLRenderer::isContextLost() | 1794 bool GLRenderer::isContextLost() |
1818 { | 1795 { |
1819 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1796 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1820 } | 1797 } |
1821 | 1798 |
1822 } // namespace cc | 1799 } // namespace cc |
OLD | NEW |