PassOwnPtr<LayerTextureUpdater> ContentLayerChromium::createTextureUpdater() { OwnPtr<LayerPainterChromium> painter = adoptPtr(new ContentLayerPainter(m_owner)); #if USE(SKIA) if (layerRenderer()->accelerateDrawing()) return adoptPtr(new LayerTextureUpdaterSkPicture(layerRendererContext(), painter.release(), layerRenderer()->skiaContext())); #endif return adoptPtr(new LayerTextureUpdaterBitmap(layerRendererContext(), painter.release(), layerRenderer()->contextSupportsMapSub())); }
void ContentLayerChromium::draw() { if (m_skipsDraw) return; ASSERT(layerRenderer()); const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues(); ASSERT(sv && sv->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture)); layerRenderer()->useShader(sv->contentShaderProgram()); GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); if (requiresClippedUpdateRect()) { float m43 = drawTransform().m43(); TransformationMatrix transform; transform.translate3d(m_largeLayerDrawRect.center().x(), m_largeLayerDrawRect.center().y(), m43); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), transform, m_largeLayerDrawRect.width(), m_largeLayerDrawRect.height(), drawOpacity(), sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); } else { drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), m_bounds.width(), m_bounds.height(), drawOpacity(), sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); } }
void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId) { if (!pixels) return; GraphicsContext3D* context = layerRendererContext(); context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); // If the texture id or size changed since last time then we need to tell GL // to re-allocate a texture. if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize) { ASSERT(bitmapSize == requiredTextureSize); GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); m_contentsTexture = textureId; m_allocatedTextureSize = requiredTextureSize; } else { ASSERT(updateRect.width() <= m_allocatedTextureSize.width() && updateRect.height() <= m_allocatedTextureSize.height()); ASSERT(updateRect.width() == bitmapSize.width() && updateRect.height() == bitmapSize.height()); GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); } m_dirtyRect.setSize(FloatSize()); // Large layers always stay dirty, because they need to update when the content rect changes. m_contentsDirty = requiresClippedUpdateRect(); }
void VideoLayerChromium::drawYUV(const SharedValues* sv) { GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::yPlane])); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::uPlane])); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane])); layerRenderer()->useShader(sv->yuvShaderProgram()); unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor)); GLC(context, context->uniform1i(sv->yTextureLocation(), 1)); GLC(context, context->uniform1i(sv->uTextureLocation(), 2)); GLC(context, context->uniform1i(sv->vTextureLocation(), 3)); GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation()); // Reset active texture back to texture 0. GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); }
void Canvas2DLayerChromium::updateCompositorResources() { if (!m_contentsDirty || !m_drawingBuffer) return; if (m_textureChanged) { // We have to generate a new backing texture. GraphicsContext3D* context = layerRendererContext(); if (m_textureId) context->deleteTexture(m_textureId); m_textureId = context->createTexture(); context->activeTexture(GraphicsContext3D::TEXTURE0); context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); IntSize size = m_drawingBuffer->size(); context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE); // Set the min-mag filters to linear and wrap modes to GraphicsContext3D::CLAMP_TO_EDGE // to get around NPOT texture limitations of GLES. context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); m_textureChanged = false; // FIXME: The finish() here is required because we have to make sure that the texture created in this // context (the compositor context) is actually created by the service side before the child context // attempts to use it (in publishToPlatformLayer). finish() is currently the only call with strong // enough semantics to promise this, but is actually much stronger. Ideally we'd do something like // inserting a fence here and waiting for it before trying to publish. context->finish(); } // Update the contents of the texture used by the compositor. if (m_contentsDirty) { m_drawingBuffer->publishToPlatformLayer(); m_contentsDirty = false; } }
Canvas2DLayerChromium::~Canvas2DLayerChromium() { if (m_textureId) layerRendererContext()->deleteTexture(m_textureId); if (m_drawingBuffer && layerRenderer()) layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get()); }
void WebGLLayerChromium::updateCompositorResources() { if (!m_context) return; if (!m_contentsDirty) return; GraphicsContext3D* rendererContext = layerRendererContext(); if (m_textureChanged) { rendererContext->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE // to get around NPOT texture limitations of GLES. rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); m_textureChanged = false; } // Update the contents of the texture used by the compositor. if (m_contentsDirty && m_textureUpdated) { // prepareTexture copies the contents of the off-screen render target into the texture // used by the compositor. // m_context->prepareTexture(); m_context->markLayerComposited(); m_contentsDirty = false; m_textureUpdated = false; } }
void VideoLayerChromium::updateContentsIfDirty() { if (!m_contentsDirty) return; RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client()); if (!backing || backing->paintingGoesToWindow()) return; ASSERT(drawsContent()); m_skipsDraw = false; VideoFrameChromium* frame = m_provider->getCurrentFrame(); if (!frame) { m_skipsDraw = true; m_provider->putCurrentFrame(frame); return; } m_frameFormat = frame->format(); unsigned textureFormat = determineTextureFormat(frame); if (textureFormat == GraphicsContext3D::INVALID_VALUE) { // FIXME: Implement other paths. notImplemented(); m_skipsDraw = true; m_provider->putCurrentFrame(frame); return; } if (frame->surfaceType() == VideoFrameChromium::TypeTexture) { releaseCurrentFrame(); saveCurrentFrame(frame); m_dirtyRect.setSize(FloatSize()); m_contentsDirty = false; return; } // Allocate textures for planes if they are not allocated already, or // reallocate textures that are the wrong size for the frame. GraphicsContext3D* context = layerRendererContext(); bool texturesAllocated = allocateTexturesIfNeeded(context, frame, textureFormat); if (!texturesAllocated) { m_skipsDraw = true; m_provider->putCurrentFrame(frame); return; } // Update texture planes. for (unsigned plane = 0; plane < frame->planes(); plane++) { ASSERT(frame->requiredTextureSize(plane) == m_textureSizes[plane]); updateTexture(context, m_textures[plane], frame->requiredTextureSize(plane), textureFormat, frame->data(plane)); } m_dirtyRect.setSize(FloatSize()); m_contentsDirty = false; m_provider->putCurrentFrame(frame); }
void VideoLayerChromium::cleanupResources() { LayerChromium::cleanupResources(); releaseCurrentFrame(); if (!layerRenderer()) return; GraphicsContext3D* context = layerRendererContext(); for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) { if (m_textures[plane]) GLC(context, context->deleteTexture(m_textures[plane])); } }
void ContentLayerChromium::draw() { if (m_skipsDraw) return; ASSERT(layerRenderer()); const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues(); ASSERT(sv && sv->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture)); layerRenderer()->useShader(sv->contentShaderProgram()); GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); }
void VideoLayerChromium::drawRGBA(const SharedValues* sv) { GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane])); layerRenderer()->useShader(sv->rgbaShaderProgram()); unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width(); unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width(); float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor)); GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0)); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation()); }
void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId, MipmapUse requestMipmap) { if (!pixels) return; GraphicsContext3D* context = layerRendererContext(); context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); bool generateMipmap = (requestMipmap == useMipmap) && (layerRenderer()->contentLayerSharedValues()->npotSupported() || (isPowerOfTwo(updateRect.width()) && isPowerOfTwo(updateRect.height()))); // If the texture id or size changed since last time then we need to tell GL // to re-allocate a texture. if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize) { ASSERT(bitmapSize == requiredTextureSize); GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); if (generateMipmap) { GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR_MIPMAP_LINEAR)); GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); } else { 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)); } m_contentsTexture = textureId; m_allocatedTextureSize = requiredTextureSize; } else { ASSERT(updateRect.width() <= m_allocatedTextureSize.width() && updateRect.height() <= m_allocatedTextureSize.height()); ASSERT(updateRect.width() == bitmapSize.width() && updateRect.height() == bitmapSize.height()); GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); } if (generateMipmap) GLC(context, context->generateMipmap(GraphicsContext3D::TEXTURE_2D)); m_dirtyRect.setSize(FloatSize()); m_contentsDirty = false; }
bool WebGLLayerChromium::paintRenderedResultsToCanvas(ImageBuffer* imageBuffer) { if (m_textureUpdated || !layerRendererContext() || !drawsContent()) return false; IntSize framebufferSize = context()->getInternalFramebufferSize(); ASSERT(layerRendererContext()); // This would ideally be done in the webgl context, but that isn't possible yet. Platform3DObject framebuffer = layerRendererContext()->createFramebuffer(); layerRendererContext()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer); layerRendererContext()->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_textureId, 0); Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(layerRendererContext()->getExtensions()); extensions->paintFramebufferToCanvas(framebuffer, framebufferSize.width(), framebufferSize.height(), !context()->getContextAttributes().premultipliedAlpha, imageBuffer); layerRendererContext()->deleteFramebuffer(framebuffer); return true; }