void SquareRootElement::layout( const AttributeManager* am ) { RowElement::layout( am ); kDebug(39001) << "Width: " << width(); kDebug(39001) << "Height: " << height(); double thinSpace = am->layoutSpacing( this ); double linethickness = 1; double symbolHeight = baseLine(); if( height() > symbolHeight*1.3 ) symbolHeight = height(); symbolHeight += thinSpace; double tickWidth = symbolHeight / 3.0; // Set the sqrt dimensions setWidth( tickWidth + width() + thinSpace ); setHeight( height() + thinSpace ); setBaseLine( baseLine() + thinSpace ); // Adapt the children's positions to the new offset QPointF childOffset( tickWidth + thinSpace, thinSpace ); foreach( BasicElement* element, childElements() ) element->setOrigin( element->origin() + childOffset ); // Draw the sqrt symbol into a QPainterPath as buffer m_rootSymbol = QPainterPath(); m_rootSymbol.moveTo( linethickness, 2.0 * symbolHeight / 3.0 ); m_rootSymbol.lineTo( 0 + tickWidth/2.0, symbolHeight-linethickness/2 ); m_rootSymbol.lineTo( 0 + tickWidth, linethickness/2 ); m_rootSymbol.lineTo( width() - linethickness/2, linethickness/2 ); }
void SquareRootElement::layout( const AttributeManager* am ) { RowElement::layout( am ); qreal thinSpace = am->layoutSpacing( this ); qreal symbolHeight = baseLine(); if( height() > symbolHeight*1.3 ) symbolHeight = height(); symbolHeight += thinSpace; qreal tickWidth = symbolHeight / 3.0; m_lineThickness = am->lineThickness(this); // Set the sqrt dimensions QPointF childOffset( tickWidth + thinSpace, thinSpace + m_lineThickness ); setWidth( width() + childOffset.x()); setHeight( height() + childOffset.y()); setBaseLine( baseLine() + childOffset.y()); // Adapt the children's positions to the new offset foreach( BasicElement* element, childElements() ) element->setOrigin( element->origin() + childOffset ); QRectF rect = childrenBoundingRect(); rect.translate(childOffset); setChildrenBoundingRect(rect); // Draw the sqrt symbol into a QPainterPath as buffer m_rootSymbol = QPainterPath(); m_rootSymbol.moveTo( m_lineThickness, 2.0 * symbolHeight / 3.0 ); m_rootSymbol.lineTo( 0 + tickWidth/2.0, symbolHeight-m_lineThickness/2 ); m_rootSymbol.lineTo( 0 + tickWidth, m_lineThickness/2 ); m_rootSymbol.lineTo( width() - m_lineThickness/2, m_lineThickness/2 ); }
static void ContainerRender(Container* aContainer, int aPreviousFrameBuffer, const nsIntPoint& aOffset, LayerManagerOGL* aManager) { /** * Setup our temporary texture for rendering the contents of this container. */ GLuint containerSurface; GLuint frameBuffer; nsIntPoint childOffset(aOffset); nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); nsIntRect cachedScissor = aContainer->gl()->ScissorRect(); aContainer->gl()->PushScissorRect(); aContainer->mSupportsComponentAlphaChildren = false; float opacity = aContainer->GetEffectiveOpacity(); const gfx3DMatrix& transform = aContainer->GetEffectiveTransform(); bool needsFramebuffer = aContainer->UseIntermediateSurface(); if (needsFramebuffer) { nsIntRect framebufferRect = visibleRect; // we're about to create a framebuffer backed by textures to use as an intermediate // surface. What to do if its size (as given by framebufferRect) would exceed the // maximum texture size supported by the GL? The present code chooses the compromise // of just clamping the framebuffer's size to the max supported size. // This gives us a lower resolution rendering of the intermediate surface (children layers). // See bug 827170 for a discussion. GLint maxTexSize; aContainer->gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize); framebufferRect.width = std::min(framebufferRect.width, maxTexSize); framebufferRect.height = std::min(framebufferRect.height, maxTexSize); LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear; if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff aContainer->mSupportsComponentAlphaChildren = true; mode = LayerManagerOGL::InitModeNone; } else { const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. if (HasOpaqueAncestorLayer(aContainer) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { mode = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering() ? LayerManagerOGL::InitModeCopy : LayerManagerOGL::InitModeClear; framebufferRect.x += transform.x0; framebufferRect.y += transform.y0; aContainer->mSupportsComponentAlphaChildren = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering(); } } aContainer->gl()->PushViewportRect(); framebufferRect -= childOffset; if (!aManager->CompositingDisabled()) { aManager->CreateFBOWithTexture(framebufferRect, mode, aPreviousFrameBuffer, &frameBuffer, &containerSurface); } childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; } else { frameBuffer = aPreviousFrameBuffer; aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); } nsAutoTArray<Layer*, 12> children; aContainer->SortChildrenBy3DZOrder(children); /** * Render this container's contents. */ for (uint32_t i = 0; i < children.Length(); i++) { LayerOGL* layerToRender = static_cast<LayerOGL*>(children.ElementAt(i)->ImplData()); if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { continue; } nsIntRect scissorRect = layerToRender->GetLayer()-> CalculateScissorRect(cachedScissor, &aManager->GetWorldTransform()); if (scissorRect.IsEmpty()) { continue; } aContainer->gl()->fScissor(scissorRect.x, scissorRect.y, scissorRect.width, scissorRect.height); layerToRender->RenderLayer(frameBuffer, childOffset); aContainer->gl()->MakeCurrent(); } if (needsFramebuffer) { // Unbind the current framebuffer and rebind the previous one. #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { nsRefPtr<gfxImageSurface> surf = aContainer->gl()->GetTexImage(containerSurface, true, aManager->GetFBOLayerProgramType()); WriteSnapshotToDumpFile(aContainer, surf); } #endif // Restore the viewport aContainer->gl()->PopViewportRect(); nsIntRect viewport = aContainer->gl()->ViewportRect(); aManager->SetupPipeline(viewport.width, viewport.height, LayerManagerOGL::ApplyWorldTransform); aContainer->gl()->PopScissorRect(); aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); if (!aManager->CompositingDisabled()) { aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer); aContainer->gl()->fActiveTexture(LOCAL_GL_TEXTURE0); aContainer->gl()->fBindTexture(aManager->FBOTextureTarget(), containerSurface); MaskType maskType = MaskNone; if (aContainer->GetMaskLayer()) { if (!aContainer->GetTransform().CanDraw2D()) { maskType = Mask3d; } else { maskType = Mask2d; } } ShaderProgramOGL *rgb = aManager->GetFBOLayerProgram(maskType); rgb->Activate(); rgb->SetLayerQuadRect(visibleRect); rgb->SetLayerTransform(transform); rgb->SetLayerOpacity(opacity); rgb->SetRenderOffset(aOffset); rgb->SetTextureUnit(0); rgb->LoadMask(aContainer->GetMaskLayer()); if (rgb->GetTexCoordMultiplierUniformLocation() != -1) { // 2DRect case, get the multiplier right for a sampler2DRect rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height); } // Drawing is always flipped, but when copying between surfaces we want to avoid // this. Pass true for the flip parameter to introduce a second flip // that cancels the other one out. aManager->BindAndDrawQuad(rgb, true); // Clean up resources. This also unbinds the texture. aContainer->gl()->fDeleteTextures(1, &containerSurface); } } else { aContainer->gl()->PopScissorRect(); } }
template<class ContainerT> void ContainerRender(ContainerT* aContainer, const nsIntPoint& aOffset, LayerManagerComposite* aManager, const nsIntRect& aClipRect) { /** * Setup our temporary surface for rendering the contents of this container. */ RefPtr<CompositingRenderTarget> surface; Compositor* compositor = aManager->GetCompositor(); RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget(); nsIntPoint childOffset(aOffset); nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); aContainer->mSupportsComponentAlphaChildren = false; float opacity = aContainer->GetEffectiveOpacity(); bool needsSurface = aContainer->UseIntermediateSurface(); if (needsSurface) { SurfaceInitMode mode = INIT_MODE_CLEAR; bool surfaceCopyNeeded = false; gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); // we're about to create a framebuffer backed by textures to use as an intermediate // surface. What to do if its size (as given by framebufferRect) would exceed the // maximum texture size supported by the GL? The present code chooses the compromise // of just clamping the framebuffer's size to the max supported size. // This gives us a lower resolution rendering of the intermediate surface (children layers). // See bug 827170 for a discussion. int32_t maxTextureSize = compositor->GetMaxTextureSize(); surfaceRect.width = std::min(maxTextureSize, surfaceRect.width); surfaceRect.height = std::min(maxTextureSize, surfaceRect.height); if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff aContainer->mSupportsComponentAlphaChildren = true; mode = INIT_MODE_NONE; } else { const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. if (HasOpaqueAncestorLayer(aContainer) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { mode = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering() ? INIT_MODE_COPY : INIT_MODE_CLEAR; surfaceCopyNeeded = (mode == INIT_MODE_COPY); surfaceRect.x += transform.x0; surfaceRect.y += transform.y0; aContainer->mSupportsComponentAlphaChildren = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering(); } } surfaceRect -= gfx::IntPoint(aOffset.x, aOffset.y); if (surfaceCopyNeeded) { surface = compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget); } else { surface = compositor->CreateRenderTarget(surfaceRect, mode); } compositor->SetRenderTarget(surface); childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; } else { surface = previousTarget; aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); } nsAutoTArray<Layer*, 12> children; aContainer->SortChildrenBy3DZOrder(children); /** * Render this container's contents. */ for (uint32_t i = 0; i < children.Length(); i++) { LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->ImplData()); if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() && !layerToRender->GetLayer()->AsContainerLayer()) { continue; } nsIntRect clipRect = layerToRender->GetLayer()-> CalculateScissorRect(aClipRect, &aManager->GetWorldTransform()); if (clipRect.IsEmpty()) { continue; } layerToRender->RenderLayer(childOffset, clipRect); // invariant: our GL context should be current here, I don't think we can // assert it though } if (needsSurface) { // Unbind the current surface and rebind the previous one. #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { nsRefPtr<gfxImageSurface> surf = surface->Dump(aManager->GetCompositor()); WriteSnapshotToDumpFile(aContainer, surf); } #endif compositor->SetRenderTarget(previousTarget); EffectChain effectChain; LayerManagerComposite::AddMaskEffect(aContainer->GetMaskLayer(), effectChain, !aContainer->GetTransform().CanDraw2D()); effectChain.mPrimaryEffect = new EffectRenderTarget(surface); gfx::Matrix4x4 transform; ToMatrix4x4(aContainer->GetEffectiveTransform(), transform); gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity, transform, gfx::Point(aOffset.x, aOffset.y)); } if (aContainer->GetFrameMetrics().IsScrollable()) { gfx::Matrix4x4 transform; ToMatrix4x4(aContainer->GetEffectiveTransform(), transform); const FrameMetrics& frame = aContainer->GetFrameMetrics(); LayerRect layerViewport = frame.mViewport * frame.LayersPixelsPerCSSPixel(); gfx::Rect rect(layerViewport.x, layerViewport.y, layerViewport.width, layerViewport.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawDiagnostics(gfx::Color(1.0, 0.0, 0.0, 1.0), rect, clipRect, transform, gfx::Point(aOffset.x, aOffset.y)); } }