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(); }
bool CCThreadProxy::recreateContext() { TRACE_EVENT0("cc", "CCThreadProxy::recreateContext"); ASSERT(isMainThread()); // Try to create the context. RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext(); if (!context) return false; ASSERT(context->hasOneRef()); // Leak the context pointer so we can transfer ownership of it to the other side... GraphicsContext3D* contextPtr = context.release().leakRef(); ASSERT(contextPtr->hasOneRef()); // Make a blocking call to recreateContextOnImplThread. The results of that // call are pushed into the recreateSucceeded and capabilities local // variables. CCCompletionEvent completion; bool recreateSucceeded = false; LayerRendererCapabilities capabilities; CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::recreateContextOnImplThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&recreateSucceeded), AllowCrossThreadAccess(&capabilities))); completion.wait(); if (recreateSucceeded) m_layerRendererCapabilitiesMainThreadCopy = capabilities; return recreateSucceeded; }
bool CCThreadProxy::initializeLayerRenderer() { TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0); RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D(); if (!context) return false; ASSERT(context->hasOneRef()); // Leak the context pointer so we can transfer ownership of it to the other side... GraphicsContext3D* contextPtr = context.release().leakRef(); ASSERT(contextPtr->hasOneRef()); // Make a blocking call to initializeLayerRendererOnImplThread. The results of that call // are pushed into the initializeSucceeded and capabilities local variables. CCCompletionEvent completion; bool initializeSucceeded = false; LayerRendererCapabilities capabilities; s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnImplThread, AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&initializeSucceeded), AllowCrossThreadAccess(&capabilities), AllowCrossThreadAccess(&m_compositorIdentifier))); completion.wait(); if (initializeSucceeded) m_layerRendererCapabilitiesMainThreadCopy = capabilities; return initializeSucceeded; }
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 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()); } }
bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContext* context) { GraphicsContext3D* contextSupport = context->graphicsContext3D(); return contextSupport->supportsExtension("GL_EXT_texture_compression_s3tc") || (contextSupport->supportsExtension("GL_EXT_texture_compression_dxt1") && contextSupport->supportsExtension("GL_CHROMIUM_texture_compression_dxt3") && contextSupport->supportsExtension("GL_CHROMIUM_texture_compression_dxt5")); }
void GraphicsContext3DPrivate::initializeANGLE() { ShBuiltInResources ANGLEResources; ShInitBuiltInResources(&ANGLEResources); m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs); m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors); m_context->getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors); m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits); m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits); m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits); m_context->getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors); // Always set to 1 for OpenGL ES. ANGLEResources.MaxDrawBuffers = 1; Extensions3D* extensions = m_context->getExtensions(); if (extensions->supports("GL_ARB_texture_rectangle")) ANGLEResources.ARB_texture_rectangle = 1; GC3Dint range[2], precision; m_context->getShaderPrecisionFormat(GraphicsContext3D::FRAGMENT_SHADER, GraphicsContext3D::HIGH_FLOAT, range, &precision); ANGLEResources.FragmentPrecisionHigh = (range[0] || range[1] || precision); m_context->m_compiler.setResources(ANGLEResources); }
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; } }
void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const Color& backgroundColor, bool drawsBackground, const FloatPoint& contentPosition, TextureMapper::PaintFlags PaintFlags) { if (!m_textureMapper) { m_textureMapper = TextureMapper::create(); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); } syncRemoteContent(); adjustPositionForFixedLayers(contentPosition); TextureMapperLayer* currentRootLayer = rootLayer(); if (!currentRootLayer) return; #if USE(COORDINATED_GRAPHICS_THREADED) for (auto& proxy : m_platformLayerProxies.values()) proxy->swapBuffer(); #endif currentRootLayer->setTextureMapper(m_textureMapper.get()); currentRootLayer->applyAnimationsRecursively(); m_textureMapper->beginPainting(PaintFlags); m_textureMapper->beginClip(TransformationMatrix(), clipRect); if (drawsBackground) { RGBA32 rgba = makeRGBA32FromFloats(backgroundColor.red(), backgroundColor.green(), backgroundColor.blue(), backgroundColor.alpha() * opacity); m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba)); } else { GraphicsContext3D* context = static_cast<TextureMapperGL*>(m_textureMapper.get())->graphicsContext3D(); context->clearColor(m_viewBackgroundColor.red() / 255.0f, m_viewBackgroundColor.green() / 255.0f, m_viewBackgroundColor.blue() / 255.0f, m_viewBackgroundColor.alpha() / 255.0f); context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); } if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) { currentRootLayer->setOpacity(opacity); currentRootLayer->setTransform(matrix); } currentRootLayer->paint(); m_fpsCounter.updateFPSAndDisplay(*m_textureMapper, clipRect.location(), matrix); m_textureMapper->endClip(); m_textureMapper->endPainting(); if (currentRootLayer->descendantsOrSelfHaveRunningAnimations()) { RefPtr<CoordinatedGraphicsScene> protector(this); dispatchOnClientRunLoop([=] { protector->updateViewport(); }); } }
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 ClipStack::apply(GraphicsContext3D& context) { if (clipState.scissorBox.isEmpty()) return; context.scissor(clipState.scissorBox.x(), (yAxisMode == YAxisMode::Inverted) ? size.height() - clipState.scissorBox.maxY() : clipState.scissorBox.y(), clipState.scissorBox.width(), clipState.scissorBox.height()); context.stencilOp(GraphicsContext3D::KEEP, GraphicsContext3D::KEEP, GraphicsContext3D::KEEP); context.stencilFunc(GraphicsContext3D::EQUAL, clipState.stencilIndex - 1, clipState.stencilIndex - 1); if (clipState.stencilIndex == 1) context.disable(GraphicsContext3D::STENCIL_TEST); else context.enable(GraphicsContext3D::STENCIL_TEST); }
void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity) { m_context->markLayerComposited(); blitMultisampleFramebufferAndRestoreContext(); if (textureMapper->accelerationMode() == TextureMapper::OpenGLMode) { TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper); TextureMapperGL::Flags flags = TextureMapperGL::ShouldFlipTexture | (m_context->m_attrs.alpha ? TextureMapperGL::ShouldBlend : 0); IntSize textureSize(m_context->m_currentWidth, m_context->m_currentHeight); texmapGL->drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity); return; } // Alternatively read pixels to a memory buffer. GraphicsContext* context = textureMapper->graphicsContext(); QPainter* painter = context->platformContext(); painter->save(); painter->setTransform(matrix); painter->setOpacity(opacity); const int height = m_context->m_currentHeight; const int width = m_context->m_currentWidth; painter->beginNativePainting(); makeCurrentIfNeeded(); glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_fbo); QImage offscreenImage = qt_gl_read_framebuffer(QSize(width, height), true, true); glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO); painter->endNativePainting(); painter->drawImage(targetRect, offscreenImage); painter->restore(); }
bool CCThreadProxy::initializeContext() { TRACE_EVENT("CCThreadProxy::initializeContext", this, 0); RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext(); if (!context) return false; ASSERT(context->hasOneRef()); // Leak the context pointer so we can transfer ownership of it to the other side... GraphicsContext3D* contextPtr = context.release().leakRef(); ASSERT(contextPtr->hasOneRef()); CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeContextOnImplThread, AllowCrossThreadAccess(contextPtr))); return true; }
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()); }
// Draws the layer with a single colored shader. This method is used to do // quick draws into the stencil buffer. void LayerChromium::drawAsMask() { ASSERT(layerRenderer()); const SharedValues* sv = layerRenderer()->layerSharedValues(); ASSERT(sv && sv->initialized()); layerRenderer()->useShader(sv->borderShaderProgram()); // We reuse the border shader here as all we need a single colored shader pass. // The color specified here is only for debug puproses as typically when we call this // method, writes to the color channels are disabled. GraphicsContext3D* context = layerRendererContext(); GLC(context, context->uniform4f(sv->borderShaderColorLocation(), 0, 1 , 0, 0.7)); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), sv->borderShaderMatrixLocation(), -1); }
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; } }
bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DObject texture, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY) { if (!m_data.m_layerBridge || !platformLayer()) return false; Platform3DObject sourceTexture = m_data.m_layerBridge->backBufferTexture(); if (!context.makeContextCurrent()) return false; Extensions3D* extensions = context.getExtensions(); if (!extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->supports("GL_CHROMIUM_flipy")) return false; // The canvas is stored in a premultiplied format, so unpremultiply if necessary. context.pixelStorei(Extensions3D::UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha); // The canvas is stored in an inverted position, so the flip semantics are reversed. context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, !flipY); extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, sourceTexture, texture, 0, internalFormat); context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, false); context.pixelStorei(Extensions3D::UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); context.flush(); return true; }
void WebGLProgram::cacheInfoIfNeeded() { if (m_infoValid) return; if (!object()) return; GraphicsContext3D* context = getAGraphicsContext3D(); if (!context) return; GC3Dint linkStatus = 0; context->getProgramiv(object(), GraphicsContext3D::LINK_STATUS, &linkStatus); m_linkStatus = linkStatus; if (m_linkStatus) cacheActiveAttribLocations(context); m_infoValid = true; }
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 CCCanvasLayerImpl::draw(const IntRect&) { ASSERT(layerRenderer()); const CCCanvasLayerImpl::Program* program = layerRenderer()->canvasLayerProgram(); ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRenderer()->context(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId)); GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA; GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); layerRenderer()->useShader(program->program()); GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), program->vertexShader().matrixLocation(), program->fragmentShader().alphaLocation()); }
uint32_t GraphicsContext3DPrivate::copyToGraphicsSurface() { if (!m_graphicsSurface) return 0; m_context->markLayerComposited(); blitMultisampleFramebufferAndRestoreContext(); m_graphicsSurface->copyFromTexture(m_context->m_texture, IntRect(0, 0, m_context->m_currentWidth, m_context->m_currentHeight)); return m_graphicsSurface->frontBuffer(); }
bool GraphicsContext3DPrivate::initialize(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, bool renderDirectlyToHostWindow) { PageClientEfl* pageClient = static_cast<PageClientEfl*>(hostWindow->platformPageClient()); Evas* evas = evas_object_evas_get(pageClient->view()); // Create a new Evas_GL object for gl rendering on efl. m_evasGL = evas_gl_new(evas); if (!m_evasGL) return false; // Get the API for rendering using OpenGL. // This returns a structure that contains all the OpenGL functions we can use to render in Evas m_api = evas_gl_api_get(m_evasGL); if (!m_api) return false; Evas_GL_Context* shareContext = 0; #if USE(ACCELERATED_COMPOSITING) // GC3D with RenderOffscreen style for WebGL has to be shared with AC's context when AC is enabled. if (!renderDirectlyToHostWindow) { GraphicsContext3D* context = pageClient->acceleratedCompositingContext(); if (context) shareContext = static_cast<Evas_GL_Context*>(context->platformGraphicsContext3D()); } #endif // Create a context m_context = evas_gl_context_create(m_evasGL, shareContext); if (!m_context) return false; // Create a surface if (!createSurface(pageClient, renderDirectlyToHostWindow)) return false; return makeContextCurrent(); }
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; }
void LayerChromium::drawDebugBorder() { static float glMatrix[16]; if (!borderColor().alpha()) return; ASSERT(layerRenderer()); const SharedValues* sv = layerRenderer()->layerSharedValues(); ASSERT(sv && sv->initialized()); layerRenderer()->useShader(sv->borderShaderProgram()); TransformationMatrix renderMatrix = drawTransform(); renderMatrix.scale3d(bounds().width(), bounds().height(), 1); toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->uniformMatrix4fv(sv->borderShaderMatrixLocation(), false, &glMatrix[0], 1)); GLC(context, context->uniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1)); GLC(context, context->lineWidth(borderWidth())); // The indices for the line are stored in the same array as the triangle indices. GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); }
// static void LayerChromium::prepareForDraw(const SharedValues* sv) { GraphicsContext3D* context = sv->context(); GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, sv->quadVerticesVbo())); GLC(context, context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo())); unsigned offset = 0; GLC(context, context->vertexAttribPointer(s_positionAttribLocation, 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); offset += 3 * sizeof(float); GLC(context, context->vertexAttribPointer(s_texCoordAttribLocation, 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); GLC(context, context->enableVertexAttribArray(s_positionAttribLocation)); GLC(context, context->enableVertexAttribArray(s_texCoordAttribLocation)); }
void CCVideoLayerImpl::drawNativeTexture(LayerRendererChromium* layerRenderer) const { const NativeTextureProgram* program = layerRenderer->videoLayerNativeTextureProgram(); ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRenderer->context(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_nativeTextureId)); GLC(context, context->useProgram(program->program())); float widthScaleFactor = static_cast<float>(m_nativeTextureVisibleSize.width()) / m_nativeTextureSize.width(); GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1)); GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(), program->vertexShader().matrixLocation(), program->fragmentShader().alphaLocation(), -1); }
void CCPluginLayerImpl::draw() { ASSERT(layerRenderer()); const CCPluginLayerImpl::Program* program = layerRenderer()->pluginLayerProgram(); ASSERT(program && program->initialized()); 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)); layerRenderer()->useShader(program->program()); GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), program->vertexShader().matrixLocation(), program->fragmentShader().alphaLocation()); }
void CCHeadsUpDisplay::draw() { GraphicsContext3D* context = m_layerRenderer->context(); if (!m_hudTexture) m_hudTexture = ManagedTexture::create(m_layerRenderer->renderSurfaceTextureManager()); // Use a fullscreen texture only if we need to... IntSize hudSize; if (settings().showPlatformLayerTree) { hudSize.setWidth(min(2048, m_layerRenderer->viewportWidth())); hudSize.setHeight(min(2048, m_layerRenderer->viewportHeight())); } else { hudSize.setWidth(512); hudSize.setHeight(128); } if (!m_hudTexture->reserve(hudSize, GraphicsContext3D::RGBA)) return; // Render pixels into the texture. PlatformCanvas canvas; canvas.resize(hudSize); { PlatformCanvas::Painter painter(&canvas, PlatformCanvas::Painter::GrayscaleText); drawHudContents(painter.context(), hudSize); } // Upload to GL. { PlatformCanvas::AutoLocker locker(&canvas); m_hudTexture->bindTexture(context, m_layerRenderer->renderSurfaceTextureAllocator()); bool uploadedViaMap = false; if (m_useMapSubForUploads) { Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions()); uint8_t* pixelDest = static_cast<uint8_t*>(extensions->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, hudSize.width(), hudSize.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY)); if (pixelDest) { uploadedViaMap = true; memcpy(pixelDest, locker.pixels(), hudSize.width() * hudSize.height() * 4); extensions->unmapTexSubImage2DCHROMIUM(pixelDest); } } if (!uploadedViaMap) { GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels())); } } // Draw the HUD onto the default render surface. const Program* program = m_layerRenderer->headsUpDisplayProgram(); ASSERT(program && program->initialized()); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); m_hudTexture->bindTexture(context, m_layerRenderer->renderSurfaceTextureAllocator()); GLC(context, context->useProgram(program->program())); GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); TransformationMatrix matrix; matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0); m_layerRenderer->drawTexturedQuad(matrix, hudSize.width(), hudSize.height(), 1.0f, m_layerRenderer->sharedGeometryQuad(), program->vertexShader().matrixLocation(), program->fragmentShader().alphaLocation(), -1); m_hudTexture->unreserve(); }
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)); }
// static bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext) { GraphicsContext3D* context = webglContext->graphicsContext3D(); // This is called after we make sure GL_EXT_draw_buffers is supported. GC3Dint maxDrawBuffers = 0; GC3Dint maxColorAttachments = 0; context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers); context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments); if (maxDrawBuffers < 4 || maxColorAttachments < 4) return false; Platform3DObject fbo = context->createFramebuffer(); context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fbo); const unsigned char buffer[4] = { 0, 0, 0, 0 }; // textures are required to be initialized for other ports. bool supportsDepth = (context->getExtensions()->supports("GL_CHROMIUM_depth_texture") || context->getExtensions()->supports("GL_OES_depth_texture") || context->getExtensions()->supports("GL_ARB_depth_texture")); bool supportsDepthStencil = (context->getExtensions()->supports("GL_EXT_packed_depth_stencil") || context->getExtensions()->supports("GL_OES_packed_depth_stencil")); Platform3DObject depthStencil = 0; if (supportsDepthStencil) { depthStencil = context->createTexture(); context->bindTexture(GraphicsContext3D::TEXTURE_2D, depthStencil); context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::DEPTH_STENCIL, 1, 1, 0, GraphicsContext3D::DEPTH_STENCIL, GraphicsContext3D::UNSIGNED_INT_24_8, buffer); } Platform3DObject depth = 0; if (supportsDepth) { depth = context->createTexture(); context->bindTexture(GraphicsContext3D::TEXTURE_2D, depth); context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::DEPTH_COMPONENT, 1, 1, 0, GraphicsContext3D::DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_INT, buffer); } Vector<Platform3DObject> colors; bool ok = true; GC3Dint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments); for (GC3Dint i = 0; i < maxAllowedBuffers; ++i) { Platform3DObject color = context->createTexture(); colors.append(color); context->bindTexture(GraphicsContext3D::TEXTURE_2D, color); context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, buffer); context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0 + i, GraphicsContext3D::TEXTURE_2D, color, 0); if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) { ok = false; break; } if (supportsDepth) { context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depth, 0); if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) { ok = false; break; } context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0); } if (supportsDepthStencil) { context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depthStencil, 0); context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depthStencil, 0); if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) { ok = false; break; } context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0); context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0); } } webglContext->restoreCurrentFramebuffer(); context->deleteFramebuffer(fbo); webglContext->restoreCurrentTexture2D(); if (supportsDepth) context->deleteTexture(depth); if (supportsDepthStencil) context->deleteTexture(depthStencil); for (auto& color : colors) context->deleteTexture(color); return ok; }