2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #if USE(ACCELERATED_COMPOSITING)
30 #include "cc/CCPluginLayerImpl.h"
32 #include "Extensions3DChromium.h"
33 #include "GraphicsContext3D.h"
34 #include "LayerRendererChromium.h"
35 #include "cc/CCProxy.h"
36 #include <wtf/text/WTFString.h>
40 struct PluginProgramBinding {
41 template<class Program> void set(Program* program)
43 ASSERT(program && program->initialized());
44 programId = program->program();
45 samplerLocation = program->fragmentShader().samplerLocation();
46 matrixLocation = program->vertexShader().matrixLocation();
47 alphaLocation = program->fragmentShader().alphaLocation();
55 struct TexStretchPluginProgramBinding : PluginProgramBinding {
56 template<class Program> void set(Program* program)
58 PluginProgramBinding::set(program);
59 offsetLocation = program->vertexShader().offsetLocation();
60 scaleLocation = program->vertexShader().scaleLocation();
66 struct TexTransformPluginProgramBinding : PluginProgramBinding {
67 template<class Program> void set(Program* program)
69 PluginProgramBinding::set(program);
70 texTransformLocation = program->vertexShader().texTransformLocation();
72 int texTransformLocation;
75 } // anonymous namespace
79 CCPluginLayerImpl::CCPluginLayerImpl(int id)
83 , m_uvRect(0, 0, 1, 1)
86 , m_ioSurfaceHeight(0)
87 , m_ioSurfaceChanged(false)
88 , m_ioSurfaceTextureId(0)
92 CCPluginLayerImpl::~CCPluginLayerImpl()
97 void CCPluginLayerImpl::draw(LayerRendererChromium* layerRenderer)
99 ASSERT(CCProxy::isImplThread());
101 if (m_ioSurfaceChanged) {
102 GraphicsContext3D* context = layerRenderer->context();
103 Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions());
104 ASSERT(extensions->supports("GL_CHROMIUM_iosurface"));
105 ASSERT(extensions->supports("GL_ARB_texture_rectangle"));
107 if (!m_ioSurfaceTextureId)
108 m_ioSurfaceTextureId = context->createTexture();
110 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
111 GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId));
112 GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
113 GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
114 GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
115 GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
116 extensions->texImageIOSurface2DCHROMIUM(Extensions3D::TEXTURE_RECTANGLE_ARB,
121 // Do not check for error conditions. texImageIOSurface2DCHROMIUM is supposed to hold on to
122 // the last good IOSurface if the new one is already closed. This is only a possibility
123 // during live resizing of plugins. However, it seems that this is not sufficient to
124 // completely guard against garbage being drawn. If this is found to be a significant issue,
125 // it may be necessary to explicitly tell the embedder when to free the surfaces it has
127 m_ioSurfaceChanged = false;
130 if (m_ioSurfaceTextureId) {
131 TexTransformPluginProgramBinding binding;
133 binding.set(layerRenderer->pluginLayerTexRectProgramFlip());
135 binding.set(layerRenderer->pluginLayerTexRectProgram());
137 GraphicsContext3D* context = layerRenderer->context();
138 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
139 GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId));
141 GLC(context, context->useProgram(binding.programId));
142 GLC(context, context->uniform1i(binding.samplerLocation, 0));
143 // Note: this code path ignores m_uvRect.
144 GLC(context, context->uniform4f(binding.texTransformLocation, 0, 0, m_ioSurfaceWidth, m_ioSurfaceHeight));
145 layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
146 binding.matrixLocation,
147 binding.alphaLocation,
149 GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, 0));
151 TexStretchPluginProgramBinding binding;
153 binding.set(layerRenderer->pluginLayerProgramFlip());
155 binding.set(layerRenderer->pluginLayerProgram());
157 GraphicsContext3D* context = layerRenderer->context();
158 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
159 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
161 // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
162 // where it will only happen once per texture.
163 GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
164 GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
165 GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
166 GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
168 GLC(context, context->useProgram(binding.programId));
169 GLC(context, context->uniform1i(binding.samplerLocation, 0));
170 GLC(context, context->uniform2f(binding.offsetLocation, m_uvRect.x(), m_uvRect.y()));
171 GLC(context, context->uniform2f(binding.scaleLocation, m_uvRect.width(), m_uvRect.height()));
172 layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
173 binding.matrixLocation,
174 binding.alphaLocation,
180 void CCPluginLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
182 writeIndent(ts, indent);
183 ts << "plugin layer texture id: " << m_textureId << "\n";
184 CCLayerImpl::dumpLayerProperties(ts, indent);
187 void CCPluginLayerImpl::setIOSurfaceProperties(int width, int height, uint32_t ioSurfaceId)
189 if (m_ioSurfaceId != ioSurfaceId)
190 m_ioSurfaceChanged = true;
192 m_ioSurfaceWidth = width;
193 m_ioSurfaceHeight = height;
194 m_ioSurfaceId = ioSurfaceId;
197 void CCPluginLayerImpl::cleanupResources()
199 // FIXME: it seems there is no layer renderer / GraphicsContext3D available here. Ideally we
200 // would like to delete m_ioSurfaceTextureId.
201 m_ioSurfaceTextureId = 0;
204 } // namespace WebCore
206 #endif // USE(ACCELERATED_COMPOSITING)