void CCTextureLayerImpl::willDraw(LayerRendererChromium* layerRenderer) { CCLayerImpl::willDraw(layerRenderer); if (m_ioSurfaceChanged) { GraphicsContext3D* context = layerRenderer->context(); Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions()); ASSERT(extensions->supports("GL_CHROMIUM_iosurface")); ASSERT(extensions->supports("GL_ARB_texture_rectangle")); if (!m_ioSurfaceTextureId) m_ioSurfaceTextureId = context->createTexture(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); extensions->texImageIOSurface2DCHROMIUM(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceSize.width(), m_ioSurfaceSize.height(), m_ioSurfaceId, 0); // Do not check for error conditions. texImageIOSurface2DCHROMIUM is supposed to hold on to // the last good IOSurface if the new one is already closed. This is only a possibility // during live resizing of plugins. However, it seems that this is not sufficient to // completely guard against garbage being drawn. If this is found to be a significant issue, // it may be necessary to explicitly tell the embedder when to free the surfaces it has // allocated. m_ioSurfaceChanged = false; } }
void CCPluginLayerImpl::draw(LayerRendererChromium* layerRenderer) { ASSERT(CCProxy::isImplThread()); if (m_ioSurfaceChanged) { GraphicsContext3D* context = layerRenderer->context(); Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions()); ASSERT(extensions->supports("GL_CHROMIUM_iosurface")); ASSERT(extensions->supports("GL_ARB_texture_rectangle")); if (!m_ioSurfaceTextureId) m_ioSurfaceTextureId = context->createTexture(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); extensions->texImageIOSurface2DCHROMIUM(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceWidth, m_ioSurfaceHeight, m_ioSurfaceId, 0); // Do not check for error conditions. texImageIOSurface2DCHROMIUM is supposed to hold on to // the last good IOSurface if the new one is already closed. This is only a possibility // during live resizing of plugins. However, it seems that this is not sufficient to // completely guard against garbage being drawn. If this is found to be a significant issue, // it may be necessary to explicitly tell the embedder when to free the surfaces it has // allocated. m_ioSurfaceChanged = false; } if (m_ioSurfaceTextureId) { TexTransformPluginProgramBinding binding; if (m_flipped) binding.set(layerRenderer->pluginLayerTexRectProgramFlip()); else binding.set(layerRenderer->pluginLayerTexRectProgram()); GraphicsContext3D* context = layerRenderer->context(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId)); GLC(context, context->useProgram(binding.programId)); GLC(context, context->uniform1i(binding.samplerLocation, 0)); // Note: this code path ignores m_uvRect. GLC(context, context->uniform4f(binding.texTransformLocation, 0, 0, m_ioSurfaceWidth, m_ioSurfaceHeight)); layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(), binding.matrixLocation, binding.alphaLocation, -1); GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, 0)); } else { TexStretchPluginProgramBinding binding; if (m_flipped) binding.set(layerRenderer->pluginLayerProgramFlip()); else binding.set(layerRenderer->pluginLayerProgram()); GraphicsContext3D* context = layerRenderer->context(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId)); // FIXME: setting the texture parameters every time is redundant. Move this code somewhere // where it will only happen once per texture. GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); GLC(context, context->useProgram(binding.programId)); GLC(context, context->uniform1i(binding.samplerLocation, 0)); GLC(context, context->uniform2f(binding.offsetLocation, m_uvRect.x(), m_uvRect.y())); GLC(context, context->uniform2f(binding.scaleLocation, m_uvRect.width(), m_uvRect.height())); layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(), binding.matrixLocation, binding.alphaLocation, -1); } }