1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 33 #if USE(ACCELERATED_COMPOSITING) 34 35 #include "Canvas2DLayerChromium.h" 36 37 #include "DrawingBuffer.h" 38 #include "GraphicsContext3D.h" 39 #include "LayerRendererChromium.h" 40 41 namespace WebCore { 42 43 PassRefPtr<Canvas2DLayerChromium> Canvas2DLayerChromium::create(DrawingBuffer* drawingBuffer, GraphicsLayerChromium* owner) 44 { 45 return adoptRef(new Canvas2DLayerChromium(drawingBuffer, owner)); 46 } 47 48 Canvas2DLayerChromium::Canvas2DLayerChromium(DrawingBuffer* drawingBuffer, GraphicsLayerChromium* owner) 49 : CanvasLayerChromium(owner) 50 , m_drawingBuffer(drawingBuffer) 51 { 52 } 53 54 Canvas2DLayerChromium::~Canvas2DLayerChromium() 55 { 56 if (m_textureId) 57 layerRendererContext()->deleteTexture(m_textureId); 58 if (m_drawingBuffer && layerRenderer()) 59 layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get()); 60 } 61 62 void Canvas2DLayerChromium::updateCompositorResources() 63 { 64 if (!m_contentsDirty || !m_drawingBuffer) 65 return; 66 if (m_textureChanged) { // We have to generate a new backing texture. 67 GraphicsContext3D* context = layerRendererContext(); 68 if (m_textureId) 69 context->deleteTexture(m_textureId); 70 m_textureId = context->createTexture(); 71 context->activeTexture(GraphicsContext3D::TEXTURE0); 72 context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); 73 IntSize size = m_drawingBuffer->size(); 74 context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE); 75 // Set the min-mag filters to linear and wrap modes to GraphicsContext3D::CLAMP_TO_EDGE 76 // to get around NPOT texture limitations of GLES. 77 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); 78 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); 79 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); 80 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); 81 m_textureChanged = false; 82 // FIXME: The finish() here is required because we have to make sure that the texture created in this 83 // context (the compositor context) is actually created by the service side before the child context 84 // attempts to use it (in publishToPlatformLayer). finish() is currently the only call with strong 85 // enough semantics to promise this, but is actually much stronger. Ideally we'd do something like 86 // inserting a fence here and waiting for it before trying to publish. 87 context->finish(); 88 } 89 // Update the contents of the texture used by the compositor. 90 if (m_contentsDirty) { 91 m_drawingBuffer->publishToPlatformLayer(); 92 m_contentsDirty = false; 93 } 94 } 95 96 void Canvas2DLayerChromium::setTextureChanged() 97 { 98 m_textureChanged = true; 99 } 100 101 unsigned Canvas2DLayerChromium::textureId() const 102 { 103 return m_textureId; 104 } 105 106 void Canvas2DLayerChromium::setDrawingBuffer(DrawingBuffer* drawingBuffer) 107 { 108 if (drawingBuffer != m_drawingBuffer) { 109 if (m_drawingBuffer && layerRenderer()) 110 layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get()); 111 112 m_drawingBuffer = drawingBuffer; 113 m_textureChanged = true; 114 115 if (drawingBuffer && layerRenderer()) 116 layerRenderer()->addChildContext(m_drawingBuffer->graphicsContext3D().get()); 117 } 118 } 119 120 void Canvas2DLayerChromium::setLayerRenderer(LayerRendererChromium* newLayerRenderer) 121 { 122 if (layerRenderer() != newLayerRenderer) { 123 if (m_drawingBuffer->graphicsContext3D()) { 124 if (layerRenderer()) 125 layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get()); 126 if (newLayerRenderer) 127 newLayerRenderer->addChildContext(m_drawingBuffer->graphicsContext3D().get()); 128 } 129 130 LayerChromium::setLayerRenderer(newLayerRenderer); 131 } 132 } 133 134 } 135 #endif // USE(ACCELERATED_COMPOSITING) 136