void RenderViewMLGPU::Prepare() { if (!mTarget) { return; } // Prepare front-to-back passes. These are only present when using the depth // buffer, and they contain only opaque data. for (RefPtr<RenderPassMLGPU>& pass : mFrontToBack) { pass->PrepareForRendering(); } // Prepare the Clear buffer, which will fill the render target with // transparent pixels. This must happen before we set up world constants, // since it can create new z-indices. PrepareClears(); // Prepare the world constant buffer. This must be called after we've // finished allocating all z-indices. { WorldConstants vsConstants; Matrix4x4 projection = Matrix4x4::Translation(-1.0, 1.0, 0.0); projection.PreScale(2.0 / float(mTarget->GetSize().width), 2.0 / float(mTarget->GetSize().height), 1.0f); projection.PreScale(1.0f, -1.0f, 1.0f); memcpy(vsConstants.projection, &projection._11, 64); vsConstants.targetOffset = Point(mTargetOffset); vsConstants.sortIndexOffset = PrepareDepthBuffer(); vsConstants.debugFrameNumber = mBuilder->GetManager()->GetDebugFrameNumber(); SharedConstantBuffer* shared = mDevice->GetSharedVSBuffer(); if (!shared->Allocate(&mWorldConstants, vsConstants)) { return; } } // Prepare back-to-front passes. In depth buffer mode, these contain draw // calls that might produce transparent pixels. When using CPU-based occlusion // culling, all draw calls are back-to-front. for (RefPtr<RenderPassMLGPU>& pass : mBackToFront) { pass->PrepareForRendering(); } // Now, process children. for (const auto& iter : mChildren) { iter->Prepare(); } }
Matrix4x4 ReadTransforms(const nsCSSValueList* aList, nsStyleContext* aContext, nsPresContext* aPresContext, RuleNodeCacheConditions& aConditions, TransformReferenceBox& aRefBox, float aAppUnitsPerMatrixUnit, bool* aContains3dTransform) { Matrix4x4 result; for (const nsCSSValueList* curr = aList; curr != nullptr; curr = curr->mNext) { const nsCSSValue &currElem = curr->mValue; if (currElem.GetUnit() != eCSSUnit_Function) { NS_ASSERTION(currElem.GetUnit() == eCSSUnit_None && !aList->mNext, "stream should either be a list of functions or a " "lone None"); continue; } NS_ASSERTION(currElem.GetArrayValue()->Count() >= 1, "Incoming function is too short!"); /* Read in a single transform matrix. */ MatrixForTransformFunction(result, currElem.GetArrayValue(), aContext, aPresContext, aConditions, aRefBox, aContains3dTransform); } float scale = float(nsPresContext::AppUnitsPerCSSPixel()) / aAppUnitsPerMatrixUnit; result.PreScale(1/scale, 1/scale, 1/scale); result.PostScale(scale, scale, scale); return result; }
/* Helper function to set up a scale matrix. */ static void ProcessScaleHelper(Matrix4x4& aMatrix, float aXScale, float aYScale, float aZScale) { aMatrix.PreScale(aXScale, aYScale, aZScale); }
Matrix4x4 HostLayer::GetShadowTransform() { Matrix4x4 transform = mShadowTransform; Layer* layer = GetLayer(); transform.PostScale(layer->GetPostXScale(), layer->GetPostYScale(), 1.0f); if (const ContainerLayer* c = layer->AsContainerLayer()) { transform.PreScale(c->GetPreXScale(), c->GetPreYScale(), 1.0f); } return transform; }
/* * Scale this transform by [x], [y], and [z]. If [local] is true then * the operation is performed in local space, otherwise it is performed in world space. * If world space is used, it takes into account the aggregated transform of the scene * object's ancestors. */ void SceneObjectTransform::Scale(Real x, Real y, Real z, Bool local) { if (!local) { Matrix4x4 scaleMat; scaleMat.PreScale(x, y, z); Transform worldTrans; worldTrans.SetTo(scaleMat); Transform localTrans; GetLocalTransformationFromWorldTransformation(worldTrans, localTrans); this->TransformBy(localTrans); } else { Transform::Scale(x, y, z, true); } }
void TextRenderer::RenderText(const string& aText, const IntPoint& aOrigin, const Matrix4x4& aTransform, uint32_t aTextSize, uint32_t aTargetPixelWidth) { EnsureInitialized(); // For now we only have a bitmap font with a 16px cell size, so we just // scale it up if the user wants larger text. Float scaleFactor = Float(aTextSize) / Float(sCellHeight); aTargetPixelWidth /= scaleFactor; uint32_t numLines = 1; uint32_t maxWidth = 0; uint32_t lineWidth = 0; // Calculate the size of the surface needed to draw all the glyphs. for (uint32_t i = 0; i < aText.length(); i++) { // Insert a line break if we go past the TargetPixelWidth. // XXX - this has the downside of overrunning the intended width, causing // things at the edge of a window to be cut off. if (aText[i] == '\n' || (aText[i] == ' ' && lineWidth > aTargetPixelWidth)) { numLines++; lineWidth = 0; continue; } lineWidth += sGlyphWidths[uint32_t(aText[i])]; maxWidth = std::max(lineWidth, maxWidth); } // Create a surface to draw our glyphs to. RefPtr<DataSourceSurface> textSurf = Factory::CreateDataSourceSurface(IntSize(maxWidth, numLines * sCellHeight), sTextureFormat); if (NS_WARN_IF(!textSurf)) { return; } DataSourceSurface::MappedSurface map; if (NS_WARN_IF(!textSurf->Map(DataSourceSurface::MapType::READ_WRITE, &map))) { return; } // Initialize the surface to transparent white. memset(map.mData, uint8_t(sBackgroundOpacity * 255.0f), numLines * sCellHeight * map.mStride); uint32_t currentXPos = 0; uint32_t currentYPos = 0; // Copy our glyphs onto the surface. for (uint32_t i = 0; i < aText.length(); i++) { if (aText[i] == '\n' || (aText[i] == ' ' && currentXPos > aTargetPixelWidth)) { currentYPos += sCellHeight; currentXPos = 0; continue; } uint32_t glyphXOffset = aText[i] % (sTextureWidth / sCellWidth) * sCellWidth * BytesPerPixel(sTextureFormat); uint32_t truncatedLine = aText[i] / (sTextureWidth / sCellWidth); uint32_t glyphYOffset = truncatedLine * sCellHeight * mMap.mStride; for (int y = 0; y < 16; y++) { memcpy(map.mData + (y + currentYPos) * map.mStride + currentXPos * BytesPerPixel(sTextureFormat), mMap.mData + glyphYOffset + y * mMap.mStride + glyphXOffset, sGlyphWidths[uint32_t(aText[i])] * BytesPerPixel(sTextureFormat)); } currentXPos += sGlyphWidths[uint32_t(aText[i])]; } textSurf->Unmap(); RefPtr<DataTextureSource> src = mCompositor->CreateDataTextureSource(); if (!src->Update(textSurf)) { // Upload failed. return; } RefPtr<EffectRGB> effect = new EffectRGB(src, true, SamplingFilter::LINEAR); EffectChain chain; chain.mPrimaryEffect = effect; Matrix4x4 transform = aTransform; transform.PreScale(scaleFactor, scaleFactor, 1.0f); mCompositor->DrawQuad(Rect(aOrigin.x, aOrigin.y, maxWidth, numLines * 16), IntRect(-10000, -10000, 20000, 20000), chain, 1.0f, transform); }