bool ThreadedCompositor::tryEnsureGLContext() { if (!glContext()) return false; glContext()->makeContextCurrent(); glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height()); return true; }
void LayerTreeHostGtk::flushAndRenderLayers() { { RefPtr<LayerTreeHostGtk> protect(this); m_webPage->layoutIfNeeded(); if (!m_isValid) return; } GLContext* context = glContext(); if (!context || !context->makeContextCurrent()) return; m_lastFlushTime = currentTime(); if (!flushPendingLayerChanges()) return; // Our model is very simple. We always composite and render the tree immediately after updating it. compositeLayersToContext(); if (m_notifyAfterScheduledLayerFlush) { // Let the drawing area know that we've done a flush of the layer changes. static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers(); m_notifyAfterScheduledLayerFlush = false; } }
void ThreadedCompositor::renderLayerTree() { if (!m_scene) return; #if PLATFORM(GTK) if (!m_scene->isActive()) return; #endif if (!tryEnsureGLContext()) return; #if PLATFORM(WPE) m_target->frameWillRender(); #endif FloatRect clipRect(0, 0, m_viewportSize.width(), m_viewportSize.height()); TransformationMatrix viewportTransform; FloatPoint scrollPostion = m_viewportController->visibleContentsRect().location(); viewportTransform.scale(m_viewportController->pageScaleFactor() * m_deviceScaleFactor); viewportTransform.translate(-scrollPostion.x(), -scrollPostion.y()); if (!m_drawsBackground) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); } m_scene->paintToCurrentGLContext(viewportTransform, 1, clipRect, Color::transparent, !m_drawsBackground, scrollPostion); glContext()->swapBuffers(); #if PLATFORM(WPE) m_target->frameRendered(); #endif }
bool ThreadedCompositor::ensureGLContext() { if (!glContext()) return false; glContext()->makeContextCurrent(); // The window size may be out of sync with the page size at this point, and getting // the viewport parameters incorrect, means that the content will be misplaced. Thus // we set the viewport parameters directly from the window size. IntSize contextSize = glContext()->defaultFrameBufferSize(); if (m_viewportSize != contextSize) { glViewport(0, 0, contextSize.width(), contextSize.height()); m_viewportSize = contextSize; } return true; }
void FrameRenderer::render( Camera& cam, Node& root ) const { /* Update world transforms. */ root.updateWorldTransform(); glContext().makeCurrent(); render( cam, root, *pimpl->viewport ); }
JSValue JSHTMLCanvasElement::getContext(ExecState* exec) { HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(impl()); const UString& contextId = exec->argument(0).toString(exec)->value(exec); RefPtr<CanvasContextAttributes> attrs; #if ENABLE(WEBGL) if (contextId == "experimental-webgl" || contextId == "webkit-3d") { attrs = WebGLContextAttributes::create(); WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get()); if (exec->argumentCount() > 1 && exec->argument(1).isObject()) { JSObject* jsAttrs = exec->argument(1).getObject(); Identifier alpha(exec, "alpha"); if (jsAttrs->hasProperty(exec, alpha)) webGLAttrs->setAlpha(jsAttrs->get(exec, alpha).toBoolean(exec)); Identifier depth(exec, "depth"); if (jsAttrs->hasProperty(exec, depth)) webGLAttrs->setDepth(jsAttrs->get(exec, depth).toBoolean(exec)); Identifier stencil(exec, "stencil"); if (jsAttrs->hasProperty(exec, stencil)) webGLAttrs->setStencil(jsAttrs->get(exec, stencil).toBoolean(exec)); Identifier antialias(exec, "antialias"); if (jsAttrs->hasProperty(exec, antialias)) webGLAttrs->setAntialias(jsAttrs->get(exec, antialias).toBoolean(exec)); Identifier premultipliedAlpha(exec, "premultipliedAlpha"); if (jsAttrs->hasProperty(exec, premultipliedAlpha)) webGLAttrs->setPremultipliedAlpha(jsAttrs->get(exec, premultipliedAlpha).toBoolean(exec)); Identifier preserveDrawingBuffer(exec, "preserveDrawingBuffer"); if (jsAttrs->hasProperty(exec, preserveDrawingBuffer)) webGLAttrs->setPreserveDrawingBuffer(jsAttrs->get(exec, preserveDrawingBuffer).toBoolean(exec)); } } #endif CanvasRenderingContext* context = canvas->getContext(ustringToString(contextId), attrs.get()); if (!context) return jsNull(); JSValue jsValue = toJS(exec, globalObject(), WTF::getPtr(context)); #if ENABLE(WEBGL) if (context->is3d() && InspectorInstrumentation::hasFrontends()) { ScriptObject glContext(exec, jsValue.getObject()); ScriptObject wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(canvas->document(), glContext); if (!wrapped.hasNoValue()) return wrapped.jsValue(); } #endif return jsValue; }
void LayerTreeHostGtk::initialize() { m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), this); m_rootLayer->setDrawsContent(false); m_rootLayer->setSize(m_webPage->size()); // The non-composited contents are a child of the root layer. m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this); m_nonCompositedContentLayer->setDrawsContent(true); m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); m_nonCompositedContentLayer->setSize(m_webPage->size()); if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled()) m_nonCompositedContentLayer->setAcceleratesDrawing(true); #ifndef NDEBUG m_rootLayer->setName("LayerTreeHost root layer"); m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); #endif m_rootLayer->addChild(m_nonCompositedContentLayer.get()); m_nonCompositedContentLayer->setNeedsDisplay(); m_layerTreeContext.windowHandle = m_webPage->nativeWindowHandle(); GLContext* context = glContext(); if (!context) { m_isValid = false; return; } // The creation of the TextureMapper needs an active OpenGL context. context->makeContextCurrent(); m_textureMapper = TextureMapperGL::create(); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); if (m_webPage->hasPageOverlay()) { PageOverlayList& pageOverlays = m_webPage->pageOverlays(); PageOverlayList::iterator end = pageOverlays.end(); for (PageOverlayList::iterator it = pageOverlays.begin(); it != end; ++it) createPageOverlayLayer(it->get()); } scheduleLayerFlush(); }
void LayerTreeHostGtk::compositeLayersToContext() { GLContext* context = glContext(); if (!context || !context->makeContextCurrent()) return; // The window size may be out of sync with the page size at this point, and getting // the viewport parameters incorrect, means that the content will be misplaced. Thus // we set the viewport parameters directly from the window size. IntSize contextSize = m_context->defaultFrameBufferSize(); glViewport(0, 0, contextSize.width(), contextSize.height()); m_textureMapper->beginPainting(); toTextureMapperLayer(m_rootLayer.get())->paint(); m_textureMapper->endPainting(); context->swapBuffers(); }
void ThreadedCompositor::renderLayerTree() { if (!m_scene) return; if (!ensureGLContext()) return; FloatRect clipRect(0, 0, m_viewportSize.width(), m_viewportSize.height()); TransformationMatrix viewportTransform; FloatPoint scrollPostion = viewportController()->visibleContentsRect().location(); viewportTransform.scale(viewportController()->pageScaleFactor() * m_deviceScaleFactor); viewportTransform.translate(-scrollPostion.x(), -scrollPostion.y()); m_scene->paintToCurrentGLContext(viewportTransform, 1, clipRect, Color::white, false, scrollPostion); glContext()->swapBuffers(); }
/*! Factory function for scene graph backends of the distance-field glyph cache. */ QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont &font) { Q_D(QSGContext); if (!d->distanceFieldCacheManager) d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager; QSGDistanceFieldGlyphCache *cache = d->distanceFieldCacheManager->cache(font); if (!cache) { QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration(); if (platformIntegration != 0 && platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) { QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine; if (!fe->faceId().filename.isEmpty()) { QByteArray keyName = fe->faceId().filename; if (font.style() != QFont::StyleNormal) keyName += QByteArray(" I"); if (font.weight() != QFont::Normal) keyName += ' ' + QByteArray::number(font.weight()); keyName += QByteArray(" DF"); QPlatformSharedGraphicsCache *sharedGraphicsCache = platformIntegration->createPlatformSharedGraphicsCache(keyName); if (sharedGraphicsCache != 0) { sharedGraphicsCache->ensureCacheInitialized(keyName, QPlatformSharedGraphicsCache::OpenGLTexture, QPlatformSharedGraphicsCache::Alpha8); cache = new QSGSharedDistanceFieldGlyphCache(keyName, sharedGraphicsCache, d->distanceFieldCacheManager, glContext(), font); } } } if (!cache) cache = new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font); d->distanceFieldCacheManager->insertCache(font, cache); } return cache; }
void ThreadedCompositor::renderLayerTree() { if (!m_scene) return; if (!ensureGLContext()) return; FloatRect clipRect(0, 0, m_viewportSize.width(), m_viewportSize.height()); TransformationMatrix viewportTransform; FloatPoint scrollPostion = viewportController()->visibleContentsRect().location(); viewportTransform.scale(viewportController()->pageScaleFactor()); viewportTransform.translate(-scrollPostion.x(), -scrollPostion.y()); m_scene->paintToCurrentGLContext(viewportTransform, 1, clipRect, Color::white, false, scrollPostion); #if PLATFORM(BCM_RPI) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitBCMBuffer(bufferExport); #endif #if PLATFORM(BCM_NEXUS) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitBCMNexusBuffer(bufferExport); #endif #if PLATFORM(INTEL_CE) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitIntelCEBuffer(bufferExport); #endif glContext()->swapBuffers(); #if PLATFORM(GBM) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitPrimeBuffer(bufferExport); #endif }
void LayerTreeHostGtk::initialize() { m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), *this); m_rootLayer->setDrawsContent(false); m_rootLayer->setSize(m_webPage->size()); // The non-composited contents are a child of the root layer. m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), *this); m_nonCompositedContentLayer->setDrawsContent(true); m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); m_nonCompositedContentLayer->setSize(m_webPage->size()); if (m_webPage->corePage()->settings().acceleratedDrawingEnabled()) m_nonCompositedContentLayer->setAcceleratesDrawing(true); #ifndef NDEBUG m_rootLayer->setName("LayerTreeHost root layer"); m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); #endif m_rootLayer->addChild(m_nonCompositedContentLayer.get()); m_nonCompositedContentLayer->setNeedsDisplay(); m_layerTreeContext.contextID = m_webPage->nativeWindowHandle(); GLContext* context = glContext(); if (!context) return; // The creation of the TextureMapper needs an active OpenGL context. context->makeContextCurrent(); m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); // FIXME: Cretae page olverlay layers. https://bugs.webkit.org/show_bug.cgi?id=131433. scheduleLayerFlush(); }
void V8HTMLCanvasElement::getContextMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Handle<v8::Object> holder = info.Holder(); v8::Isolate* isolate = info.GetIsolate(); HTMLCanvasElement* impl = V8HTMLCanvasElement::toNative(holder); TOSTRING_VOID(V8StringResource<>, contextIdResource, info[0]); String contextId = contextIdResource; RefPtr<CanvasContextAttributes> attributes; if (contextId == "webgl" || contextId == "experimental-webgl") { RefPtr<WebGLContextAttributes> webGLAttributes = WebGLContextAttributes::create(); if (info.Length() > 1 && info[1]->IsObject()) { v8::Handle<v8::Object> jsAttributes = info[1]->ToObject(); v8::Handle<v8::String> alpha = v8AtomicString(isolate, "alpha"); if (jsAttributes->Has(alpha) && !isUndefinedOrNull(jsAttributes->Get(alpha))) webGLAttributes->setAlpha(jsAttributes->Get(alpha)->BooleanValue()); v8::Handle<v8::String> depth = v8AtomicString(isolate, "depth"); if (jsAttributes->Has(depth) && !isUndefinedOrNull(jsAttributes->Get(depth))) webGLAttributes->setDepth(jsAttributes->Get(depth)->BooleanValue()); v8::Handle<v8::String> stencil = v8AtomicString(isolate, "stencil"); if (jsAttributes->Has(stencil) && !isUndefinedOrNull(jsAttributes->Get(stencil))) webGLAttributes->setStencil(jsAttributes->Get(stencil)->BooleanValue()); v8::Handle<v8::String> antialias = v8AtomicString(isolate, "antialias"); if (jsAttributes->Has(antialias) && !isUndefinedOrNull(jsAttributes->Get(antialias))) webGLAttributes->setAntialias(jsAttributes->Get(antialias)->BooleanValue()); v8::Handle<v8::String> premultipliedAlpha = v8AtomicString(isolate, "premultipliedAlpha"); if (jsAttributes->Has(premultipliedAlpha) && !isUndefinedOrNull(jsAttributes->Get(premultipliedAlpha))) webGLAttributes->setPremultipliedAlpha(jsAttributes->Get(premultipliedAlpha)->BooleanValue()); v8::Handle<v8::String> preserveDrawingBuffer = v8AtomicString(isolate, "preserveDrawingBuffer"); if (jsAttributes->Has(preserveDrawingBuffer) && !isUndefinedOrNull(jsAttributes->Get(preserveDrawingBuffer))) webGLAttributes->setPreserveDrawingBuffer(jsAttributes->Get(preserveDrawingBuffer)->BooleanValue()); v8::Handle<v8::String> failIfMajorPerformanceCaveat = v8AtomicString(isolate, "failIfMajorPerformanceCaveat"); if (jsAttributes->Has(failIfMajorPerformanceCaveat) && !isUndefinedOrNull(jsAttributes->Get(failIfMajorPerformanceCaveat))) webGLAttributes->setFailIfMajorPerformanceCaveat(jsAttributes->Get(failIfMajorPerformanceCaveat)->BooleanValue()); } attributes = webGLAttributes; } else { RefPtr<Canvas2DContextAttributes> canvas2DAttributes = Canvas2DContextAttributes::create(); if (info.Length() > 1 && info[1]->IsObject()) { v8::Handle<v8::Object> jsAttributes = info[1]->ToObject(); v8::Handle<v8::String> alpha = v8AtomicString(isolate, "alpha"); if (jsAttributes->Has(alpha) && !isUndefinedOrNull(jsAttributes->Get(alpha))) canvas2DAttributes->setAlpha(jsAttributes->Get(alpha)->BooleanValue()); } attributes = canvas2DAttributes; } CanvasRenderingContext* result = impl->getContext(contextId, attributes.get()); if (!result) { v8SetReturnValueNull(info); return; } if (result->is2d()) { v8::Handle<v8::Value> v8Result = toV8(toCanvasRenderingContext2D(result), info.Holder(), info.GetIsolate()); if (InspectorInstrumentation::canvasAgentEnabled(&impl->document())) { ScriptState* scriptState = ScriptState::current(isolate); ScriptValue context(scriptState, v8Result); ScriptValue wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(&impl->document(), context); if (!wrapped.isEmpty()) { v8SetReturnValue(info, wrapped.v8Value()); return; } } v8SetReturnValue(info, v8Result); return; } if (result->is3d()) { v8::Handle<v8::Value> v8Result = toV8(toWebGLRenderingContext(result), info.Holder(), info.GetIsolate()); if (InspectorInstrumentation::canvasAgentEnabled(&impl->document())) { ScriptState* scriptState = ScriptState::current(isolate); ScriptValue glContext(scriptState, v8Result); ScriptValue wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(&impl->document(), glContext); if (!wrapped.isEmpty()) { v8SetReturnValue(info, wrapped.v8Value()); return; } } v8SetReturnValue(info, v8Result); return; } ASSERT_NOT_REACHED(); v8SetReturnValueNull(info); }
v8::Handle<v8::Value> V8HTMLCanvasElement::getContextCallback(const v8::Arguments& args) { INC_STATS("DOM.HTMLCanvasElement.context"); v8::Handle<v8::Object> holder = args.Holder(); HTMLCanvasElement* imp = V8HTMLCanvasElement::toNative(holder); String contextId = toWebCoreString(args[0]); RefPtr<CanvasContextAttributes> attrs; #if ENABLE(WEBGL) if (contextId == "experimental-webgl" || contextId == "webkit-3d") { attrs = WebGLContextAttributes::create(); WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get()); if (args.Length() > 1 && args[1]->IsObject()) { v8::Handle<v8::Object> jsAttrs = args[1]->ToObject(); v8::Handle<v8::String> alpha = v8::String::New("alpha"); if (jsAttrs->Has(alpha)) webGLAttrs->setAlpha(jsAttrs->Get(alpha)->BooleanValue()); v8::Handle<v8::String> depth = v8::String::New("depth"); if (jsAttrs->Has(depth)) webGLAttrs->setDepth(jsAttrs->Get(depth)->BooleanValue()); v8::Handle<v8::String> stencil = v8::String::New("stencil"); if (jsAttrs->Has(stencil)) webGLAttrs->setStencil(jsAttrs->Get(stencil)->BooleanValue()); v8::Handle<v8::String> antialias = v8::String::New("antialias"); if (jsAttrs->Has(antialias)) webGLAttrs->setAntialias(jsAttrs->Get(antialias)->BooleanValue()); v8::Handle<v8::String> premultipliedAlpha = v8::String::New("premultipliedAlpha"); if (jsAttrs->Has(premultipliedAlpha)) webGLAttrs->setPremultipliedAlpha(jsAttrs->Get(premultipliedAlpha)->BooleanValue()); v8::Handle<v8::String> preserveDrawingBuffer = v8::String::New("preserveDrawingBuffer"); if (jsAttrs->Has(preserveDrawingBuffer)) webGLAttrs->setPreserveDrawingBuffer(jsAttrs->Get(preserveDrawingBuffer)->BooleanValue()); } } #endif CanvasRenderingContext* result = imp->getContext(contextId, attrs.get()); if (!result) return v8::Null(args.GetIsolate()); else if (result->is2d()) { v8::Handle<v8::Value> v8Result = toV8(static_cast<CanvasRenderingContext2D*>(result), args.Holder(), args.GetIsolate()); if (InspectorInstrumentation::canvasAgentEnabled(imp->document())) { ScriptState* scriptState = ScriptState::forContext(v8::Context::GetCurrent()); ScriptObject context(scriptState, v8::Handle<v8::Object>::Cast(v8Result)); ScriptObject wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(imp->document(), context); if (!wrapped.hasNoValue()) return wrapped.v8Value(); } return v8Result; } #if ENABLE(WEBGL) else if (result->is3d()) { // 3D canvas contexts can hold on to lots of GPU resources, and we want to take an // opportunity to get rid of them as soon as possible when we navigate away from pages using // them. V8PerIsolateData* perIsolateData = V8PerIsolateData::from(args.GetIsolate()); perIsolateData->setShouldCollectGarbageSoon(); v8::Handle<v8::Value> v8Result = toV8(static_cast<WebGLRenderingContext*>(result), args.Holder(), args.GetIsolate()); if (InspectorInstrumentation::canvasAgentEnabled(imp->document())) { ScriptState* scriptState = ScriptState::forContext(v8::Context::GetCurrent()); ScriptObject glContext(scriptState, v8::Handle<v8::Object>::Cast(v8Result)); ScriptObject wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(imp->document(), glContext); if (!wrapped.hasNoValue()) return wrapped.v8Value(); } return v8Result; } #endif ASSERT_NOT_REACHED(); return v8::Null(args.GetIsolate()); }
static already_AddRefed<GLContextGLX> CreateGLContext(const ContextFormat& format, Display *display, GLXDrawable drawable, GLXFBConfig cfg, XVisualInfo *vinfo, GLContextGLX *shareContext, PRBool deleteDrawable, gfxXlibSurface *pixmap = nsnull) { int db = 0, err; err = sGLXLibrary.xGetFBConfigAttrib(display, cfg, GLX_DOUBLEBUFFER, &db); if (GLX_BAD_ATTRIBUTE != err) { #ifdef DEBUG printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not "); #endif } ctxErrorOccurred = false; int (*oldHandler)(Display *, XErrorEvent *); GLXContext context; TRY_AGAIN_NO_SHARING: oldHandler = XSetErrorHandler(&ctxErrorHandler); if (gGLXVersion >= 0x0103) { context = sGLXLibrary.xCreateNewContext(display, cfg, GLX_RGBA_TYPE, shareContext ? shareContext->mContext : NULL, True); } else { context = sGLXLibrary.xCreateContext(display, vinfo, shareContext ? shareContext->mContext : NULL, True); } XSync(display, False); XSetErrorHandler(oldHandler); if (!context || ctxErrorOccurred) { if (shareContext) { shareContext = nsnull; goto TRY_AGAIN_NO_SHARING; } NS_WARNING("Failed to create GLXContext!"); return nsnull; } nsRefPtr<GLContextGLX> glContext(new GLContextGLX(format, shareContext, display, drawable, context, deleteDrawable, db, pixmap)); if (!glContext->Init()) { return nsnull; } return glContext.forget(); }