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 "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "cc/gl_renderer.h" | 7 #include "cc/gl_renderer.h" |
8 | 8 |
9 #include "CCDamageTracker.h" | 9 #include "CCDamageTracker.h" |
10 #include "CCLayerQuad.h" | 10 #include "CCLayerQuad.h" |
11 #include "FloatQuad.h" | 11 #include "FloatQuad.h" |
12 #include "GrTexture.h" | |
13 #include "NotImplemented.h" | 12 #include "NotImplemented.h" |
14 #include "base/debug/trace_event.h" | 13 #include "base/debug/trace_event.h" |
15 #include "base/logging.h" | 14 #include "base/logging.h" |
16 #include "base/string_split.h" | 15 #include "base/string_split.h" |
17 #include "base/string_util.h" | 16 #include "base/string_util.h" |
18 #include "cc/geometry_binding.h" | 17 #include "cc/geometry_binding.h" |
19 #include "cc/math_util.h" | 18 #include "cc/math_util.h" |
20 #include "cc/platform_color.h" | 19 #include "cc/platform_color.h" |
21 #include "cc/proxy.h" | 20 #include "cc/proxy.h" |
22 #include "cc/render_pass.h" | 21 #include "cc/render_pass.h" |
23 #include "cc/render_surface_filters.h" | 22 #include "cc/render_surface_filters.h" |
24 #include "cc/scoped_texture.h" | 23 #include "cc/scoped_texture.h" |
25 #include "cc/settings.h" | 24 #include "cc/settings.h" |
26 #include "cc/single_thread_proxy.h" | 25 #include "cc/single_thread_proxy.h" |
27 #include "cc/stream_video_draw_quad.h" | 26 #include "cc/stream_video_draw_quad.h" |
28 #include "cc/texture_draw_quad.h" | 27 #include "cc/texture_draw_quad.h" |
29 #include "cc/video_layer_impl.h" | 28 #include "cc/video_layer_impl.h" |
30 #include "third_party/khronos/GLES2/gl2.h" | 29 #include "third_party/khronos/GLES2/gl2.h" |
31 #include "third_party/khronos/GLES2/gl2ext.h" | 30 #include "third_party/khronos/GLES2/gl2ext.h" |
32 #include "third_party/skia/include/core/SkBitmap.h" | 31 #include "third_party/skia/include/core/SkBitmap.h" |
33 #include "third_party/skia/include/core/SkColor.h" | 32 #include "third_party/skia/include/core/SkColor.h" |
| 33 #include "third_party/skia/include/gpu/GrContext.h" |
| 34 #include "third_party/skia/include/gpu/GrTexture.h" |
| 35 #include "third_party/skia/include/gpu/SkGpuDevice.h" |
| 36 #include "third_party/skia/include/gpu/SkGrTexturePixelRef.h" |
34 #include "ui/gfx/rect_conversions.h" | 37 #include "ui/gfx/rect_conversions.h" |
35 #include <public/WebGraphicsContext3D.h> | 38 #include <public/WebGraphicsContext3D.h> |
36 #include <public/WebSharedGraphicsContext3D.h> | 39 #include <public/WebSharedGraphicsContext3D.h> |
37 #include <public/WebVideoFrame.h> | 40 #include <public/WebVideoFrame.h> |
38 #include <set> | 41 #include <set> |
39 #include <string> | 42 #include <string> |
40 #include <vector> | 43 #include <vector> |
41 #include <wtf/CurrentTime.h> | 44 #include <wtf/CurrentTime.h> |
42 | 45 |
43 using namespace std; | 46 using namespace std; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 float alpha = SkColorGetA(color) / 255.0; | 327 float alpha = SkColorGetA(color) / 255.0; |
325 | 328 |
326 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(
), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, (
SkColorGetB(color) / 255.0) * alpha, alpha)); | 329 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(
), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, (
SkColorGetB(color) / 255.0) * alpha, alpha)); |
327 | 330 |
328 GLC(context(), context()->lineWidth(quad->width())); | 331 GLC(context(), context()->lineWidth(quad->width())); |
329 | 332 |
330 // The indices for the line are stored in the same array as the triangle ind
ices. | 333 // The indices for the line are stored in the same array as the triangle ind
ices. |
331 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 6
* sizeof(unsigned short))); | 334 GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 6
* sizeof(unsigned short))); |
332 } | 335 } |
333 | 336 |
| 337 static WebGraphicsContext3D* getFilterContext() |
| 338 { |
| 339 if (Proxy::hasImplThread()) |
| 340 return WebSharedGraphicsContext3D::compositorThreadContext(); |
| 341 else |
| 342 return WebSharedGraphicsContext3D::mainThreadContext(); |
| 343 } |
| 344 |
| 345 static GrContext* getFilterGrContext() |
| 346 { |
| 347 if (Proxy::hasImplThread()) |
| 348 return WebSharedGraphicsContext3D::compositorThreadGrContext(); |
| 349 else |
| 350 return WebSharedGraphicsContext3D::mainThreadGrContext(); |
| 351 } |
| 352 |
334 static inline SkBitmap applyFilters(GLRenderer* renderer, const WebKit::WebFilte
rOperations& filters, ScopedTexture* sourceTexture) | 353 static inline SkBitmap applyFilters(GLRenderer* renderer, const WebKit::WebFilte
rOperations& filters, ScopedTexture* sourceTexture) |
335 { | 354 { |
336 if (filters.isEmpty()) | 355 if (filters.isEmpty()) |
337 return SkBitmap(); | 356 return SkBitmap(); |
338 | 357 |
339 WebGraphicsContext3D* filterContext = Proxy::hasImplThread() ? WebSharedGrap
hicsContext3D::compositorThreadContext() : WebSharedGraphicsContext3D::mainThrea
dContext(); | 358 WebGraphicsContext3D* filterContext = getFilterContext(); |
340 GrContext* filterGrContext = Proxy::hasImplThread() ? WebSharedGraphicsConte
xt3D::compositorThreadGrContext() : WebSharedGraphicsContext3D::mainThreadGrCont
ext(); | 359 GrContext* filterGrContext = getFilterGrContext(); |
341 | 360 |
342 if (!filterContext || !filterGrContext) | 361 if (!filterContext || !filterGrContext) |
343 return SkBitmap(); | 362 return SkBitmap(); |
344 | 363 |
345 renderer->context()->flush(); | 364 renderer->context()->flush(); |
346 | 365 |
347 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc
eTexture->id()); | 366 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc
eTexture->id()); |
348 SkBitmap source = RenderSurfaceFilters::apply(filters, lock.textureId(), sou
rceTexture->size(), filterContext, filterGrContext); | 367 SkBitmap source = RenderSurfaceFilters::apply(filters, lock.textureId(), sou
rceTexture->size(), filterContext, filterGrContext); |
349 return source; | 368 return source; |
350 } | 369 } |
351 | 370 |
| 371 static SkBitmap applyImageFilter(GLRenderer* renderer, SkImageFilter* filter, Sc
opedTexture* sourceTexture) |
| 372 { |
| 373 if (!filter) |
| 374 return SkBitmap(); |
| 375 |
| 376 WebGraphicsContext3D* context3d = getFilterContext(); |
| 377 GrContext* grContext = getFilterGrContext(); |
| 378 |
| 379 if (!context3d || !grContext) |
| 380 return SkBitmap(); |
| 381 |
| 382 renderer->context()->flush(); |
| 383 |
| 384 ResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourc
eTexture->id()); |
| 385 |
| 386 // Wrap the source texture in a Ganesh platform texture. |
| 387 GrPlatformTextureDesc platformTextureDescription; |
| 388 platformTextureDescription.fWidth = sourceTexture->size().width(); |
| 389 platformTextureDescription.fHeight = sourceTexture->size().height(); |
| 390 platformTextureDescription.fConfig = kSkia8888_GrPixelConfig; |
| 391 platformTextureDescription.fTextureHandle = lock.textureId(); |
| 392 SkAutoTUnref<GrTexture> texture(grContext->createPlatformTexture(platformTex
tureDescription)); |
| 393 |
| 394 // Place the platform texture inside an SkBitmap. |
| 395 SkBitmap source; |
| 396 source.setConfig(SkBitmap::kARGB_8888_Config, sourceTexture->size().width(),
sourceTexture->size().height()); |
| 397 source.setPixelRef(new SkGrPixelRef(texture.get()))->unref(); |
| 398 |
| 399 // Create a scratch texture for backing store. |
| 400 GrTextureDesc desc; |
| 401 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
| 402 desc.fSampleCnt = 0; |
| 403 desc.fWidth = source.width(); |
| 404 desc.fHeight = source.height(); |
| 405 desc.fConfig = kSkia8888_GrPixelConfig; |
| 406 GrAutoScratchTexture scratchTexture(grContext, desc, GrContext::kExact_Scrat
chTexMatch); |
| 407 |
| 408 // Create a device and canvas using that backing store. |
| 409 SkGpuDevice device(grContext, scratchTexture.detach()); |
| 410 SkCanvas canvas(&device); |
| 411 |
| 412 // Draw the source bitmap through the filter to the canvas. |
| 413 SkPaint paint; |
| 414 paint.setImageFilter(filter); |
| 415 canvas.clear(0x0); |
| 416 canvas.drawSprite(source, 0, 0, &paint); |
| 417 canvas.flush(); |
| 418 context3d->flush(); |
| 419 return device.accessBitmap(false); |
| 420 } |
| 421 |
352 scoped_ptr<ScopedTexture> GLRenderer::drawBackgroundFilters(DrawingFrame& frame,
const RenderPassDrawQuad* quad, const WebKit::WebFilterOperations& filters, con
st WebTransformationMatrix& contentsDeviceTransform) | 422 scoped_ptr<ScopedTexture> GLRenderer::drawBackgroundFilters(DrawingFrame& frame,
const RenderPassDrawQuad* quad, const WebKit::WebFilterOperations& filters, con
st WebTransformationMatrix& contentsDeviceTransform) |
353 { | 423 { |
354 // This method draws a background filter, which applies a filter to any pixe
ls behind the quad and seen through its background. | 424 // This method draws a background filter, which applies a filter to any pixe
ls behind the quad and seen through its background. |
355 // The algorithm works as follows: | 425 // The algorithm works as follows: |
356 // 1. Compute a bounding box around the pixels that will be visible through
the quad. | 426 // 1. Compute a bounding box around the pixels that will be visible through
the quad. |
357 // 2. Read the pixels in the bounding box into a buffer R. | 427 // 2. Read the pixels in the bounding box into a buffer R. |
358 // 3. Apply the background filter to R, so that it is applied in the pixels'
coordinate space. | 428 // 3. Apply the background filter to R, so that it is applied in the pixels'
coordinate space. |
359 // 4. Apply the quad's inverse transform to map the pixels in R into the qua
d's content space. This implicitly | 429 // 4. Apply the quad's inverse transform to map the pixels in R into the qua
d's content space. This implicitly |
360 // clips R by the content bounds of the quad since the destination texture h
as bounds matching the quad's content. | 430 // clips R by the content bounds of the quad since the destination texture h
as bounds matching the quad's content. |
361 // 5. Draw the background texture for the contents using the same transform
as used to draw the contents itself. This is done | 431 // 5. Draw the background texture for the contents using the same transform
as used to draw the contents itself. This is done |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 WebTransformationMatrix contentsDeviceTransform = (frame.windowMatrix * fram
e.projectionMatrix * quadRectMatrix).to2dTransform(); | 505 WebTransformationMatrix contentsDeviceTransform = (frame.windowMatrix * fram
e.projectionMatrix * quadRectMatrix).to2dTransform(); |
436 | 506 |
437 // Can only draw surface if device matrix is invertible. | 507 // Can only draw surface if device matrix is invertible. |
438 if (!contentsDeviceTransform.isInvertible()) | 508 if (!contentsDeviceTransform.isInvertible()) |
439 return; | 509 return; |
440 | 510 |
441 scoped_ptr<ScopedTexture> backgroundTexture = drawBackgroundFilters(frame, q
uad, renderPass->backgroundFilters(), contentsDeviceTransform); | 511 scoped_ptr<ScopedTexture> backgroundTexture = drawBackgroundFilters(frame, q
uad, renderPass->backgroundFilters(), contentsDeviceTransform); |
442 | 512 |
443 // FIXME: Cache this value so that we don't have to do it for both the surfa
ce and its replica. | 513 // FIXME: Cache this value so that we don't have to do it for both the surfa
ce and its replica. |
444 // Apply filters to the contents texture. | 514 // Apply filters to the contents texture. |
445 SkBitmap filterBitmap = applyFilters(this, renderPass->filters(), contentsTe
xture); | 515 SkBitmap filterBitmap; |
| 516 if (renderPass->filter()) { |
| 517 filterBitmap = applyImageFilter(this, renderPass->filter(), contentsText
ure); |
| 518 } else { |
| 519 filterBitmap = applyFilters(this, renderPass->filters(), contentsTexture
); |
| 520 } |
446 scoped_ptr<ResourceProvider::ScopedReadLockGL> contentsResourceLock; | 521 scoped_ptr<ResourceProvider::ScopedReadLockGL> contentsResourceLock; |
447 unsigned contentsTextureId = 0; | 522 unsigned contentsTextureId = 0; |
448 if (filterBitmap.getTexture()) { | 523 if (filterBitmap.getTexture()) { |
449 GrTexture* texture = reinterpret_cast<GrTexture*>(filterBitmap.getTextur
e()); | 524 GrTexture* texture = reinterpret_cast<GrTexture*>(filterBitmap.getTextur
e()); |
450 contentsTextureId = texture->getTextureHandle(); | 525 contentsTextureId = texture->getTextureHandle(); |
451 } else { | 526 } else { |
452 contentsResourceLock = make_scoped_ptr(new ResourceProvider::ScopedReadL
ockGL(m_resourceProvider, contentsTexture->id())); | 527 contentsResourceLock = make_scoped_ptr(new ResourceProvider::ScopedReadL
ockGL(m_resourceProvider, contentsTexture->id())); |
453 contentsTextureId = contentsResourceLock->textureId(); | 528 contentsTextureId = contentsResourceLock->textureId(); |
454 } | 529 } |
455 | 530 |
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 | 1588 |
1514 releaseRenderPassTextures(); | 1589 releaseRenderPassTextures(); |
1515 } | 1590 } |
1516 | 1591 |
1517 bool GLRenderer::isContextLost() | 1592 bool GLRenderer::isContextLost() |
1518 { | 1593 { |
1519 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1594 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1520 } | 1595 } |
1521 | 1596 |
1522 } // namespace cc | 1597 } // namespace cc |
OLD | NEW |