mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1880523 - Use aa_stroke_filled_circle in DrawTargetWebgl. r=jrmuizel
WGR is fairly slow at generating specialized circle geometry, whereas we can generate similar geometry much faster using the AAStroke filled circle implementation now. Differential Revision: https://phabricator.services.mozilla.com/D201939
This commit is contained in:
parent
f49ecf937b
commit
ce3d9e5437
@ -3406,9 +3406,26 @@ bool SharedContextWebgl::DrawPathAccel(
|
||||
Maybe<WGR::VertexBuffer> wgrVB;
|
||||
Maybe<AAStroke::VertexBuffer> strokeVB;
|
||||
if (!aStrokeOptions) {
|
||||
wgrVB = GeneratePathVertexBuffer(
|
||||
entry->GetPath(), IntRect(-intBounds.TopLeft(), mViewportSize),
|
||||
mRasterizationTruncates, outputBuffer, outputBufferCapacity);
|
||||
if (aPath == mUnitCirclePath) {
|
||||
auto scaleFactors = pathXform.ScaleFactors();
|
||||
if (scaleFactors.AreScalesSame()) {
|
||||
Point center = pathXform.GetTranslation() - quantBounds.TopLeft();
|
||||
float radius = scaleFactors.xScale;
|
||||
AAStroke::VertexBuffer vb = AAStroke::aa_stroke_filled_circle(
|
||||
center.x, center.y, radius, (AAStroke::OutputVertex*)outputBuffer,
|
||||
outputBufferCapacity);
|
||||
if (!vb.len || (outputBuffer && vb.len > outputBufferCapacity)) {
|
||||
AAStroke::aa_stroke_vertex_buffer_release(vb);
|
||||
} else {
|
||||
strokeVB = Some(vb);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!strokeVB) {
|
||||
wgrVB = GeneratePathVertexBuffer(
|
||||
entry->GetPath(), IntRect(-intBounds.TopLeft(), mViewportSize),
|
||||
mRasterizationTruncates, outputBuffer, outputBufferCapacity);
|
||||
}
|
||||
} else {
|
||||
if (mPathAAStroke &&
|
||||
SupportsAAStroke(aPattern, aOptions, *aStrokeOptions,
|
||||
@ -3490,7 +3507,7 @@ bool SharedContextWebgl::DrawPathAccel(
|
||||
} else {
|
||||
AAStroke::aa_stroke_vertex_buffer_release(strokeVB.ref());
|
||||
}
|
||||
if (strokeVB &&
|
||||
if (strokeVB && aStrokeOptions &&
|
||||
SupportsAAStroke(aPattern, aOptions, *aStrokeOptions,
|
||||
aAllowStrokeAlpha) == AAStrokeMode::Mask) {
|
||||
// Attempt to generate a stroke mask for path.
|
||||
@ -3651,24 +3668,30 @@ void DrawTargetWebgl::DrawPath(const Path* aPath, const Pattern& aPattern,
|
||||
}
|
||||
}
|
||||
|
||||
// DrawCircle is a more specialized version of DrawPath that attempts to cache
|
||||
// a unit circle.
|
||||
// DrawCircleAccel is a more specialized version of DrawPathAccel that attempts
|
||||
// to cache a unit circle.
|
||||
bool SharedContextWebgl::DrawCircleAccel(const Point& aCenter, float aRadius,
|
||||
const Pattern& aPattern,
|
||||
const DrawOptions& aOptions,
|
||||
const StrokeOptions* aStrokeOptions) {
|
||||
// Cache a unit circle and transform it to avoid creating a path repeatedly.
|
||||
if (!mUnitCirclePath) {
|
||||
mUnitCirclePath = MakePathForCircle(*mCurrentTarget, Point(0, 0), 1);
|
||||
}
|
||||
// Scale and translate the circle to the desired shape.
|
||||
Matrix circleXform(aRadius, 0, 0, aRadius, aCenter.x, aCenter.y);
|
||||
return DrawPathAccel(mUnitCirclePath, aPattern, aOptions, aStrokeOptions,
|
||||
true, nullptr, true, &circleXform);
|
||||
}
|
||||
|
||||
void DrawTargetWebgl::DrawCircle(const Point& aOrigin, float aRadius,
|
||||
const Pattern& aPattern,
|
||||
const DrawOptions& aOptions,
|
||||
const StrokeOptions* aStrokeOptions) {
|
||||
if (ShouldAccelPath(aOptions, aStrokeOptions)) {
|
||||
// Cache a unit circle and transform it to avoid creating a path repeatedly.
|
||||
if (!mUnitCirclePath) {
|
||||
mUnitCirclePath = MakePathForCircle(*this, Point(0, 0), 1);
|
||||
}
|
||||
// Scale and translate the circle to the desired shape.
|
||||
Matrix circleXform(aRadius, 0, 0, aRadius, aOrigin.x, aOrigin.y);
|
||||
if (mSharedContext->DrawPathAccel(mUnitCirclePath, aPattern, aOptions,
|
||||
aStrokeOptions, true, nullptr, true,
|
||||
&circleXform)) {
|
||||
return;
|
||||
}
|
||||
if (ShouldAccelPath(aOptions, aStrokeOptions) &&
|
||||
mSharedContext->DrawCircleAccel(aOrigin, aRadius, aPattern, aOptions,
|
||||
aStrokeOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MarkSkiaChanged(aOptions);
|
||||
|
@ -219,6 +219,9 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
|
||||
// value to restore it to when exiting the scope.
|
||||
Maybe<bool> mTlsScope;
|
||||
|
||||
// Cached unit circle path
|
||||
RefPtr<Path> mUnitCirclePath;
|
||||
|
||||
bool Initialize();
|
||||
bool CreateShaders();
|
||||
void ResetPathVertexBuffer(bool aChanged = true);
|
||||
@ -308,6 +311,10 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
|
||||
bool aCacheable = true,
|
||||
const Matrix* aPathXform = nullptr);
|
||||
|
||||
bool DrawCircleAccel(const Point& aCenter, float aRadius,
|
||||
const Pattern& aPattern, const DrawOptions& aOptions,
|
||||
const StrokeOptions* aStrokeOptions = nullptr);
|
||||
|
||||
bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
|
||||
const Pattern& aPattern, const DrawOptions& aOptions,
|
||||
const StrokeOptions* aStrokeOptions,
|
||||
@ -386,9 +393,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
|
||||
|
||||
RefPtr<TextureHandle> mSnapshotTexture;
|
||||
|
||||
// Cached unit circle path
|
||||
RefPtr<Path> mUnitCirclePath;
|
||||
|
||||
// Store a log of clips currently pushed so that they can be used to init
|
||||
// the clip state of temporary DTs.
|
||||
struct ClipStack {
|
||||
|
@ -40,6 +40,9 @@ void aa_stroke_curve_to(Stroker* s, float c1x, float c1y, float c2x, float c2y,
|
||||
float x, float y, bool end);
|
||||
void aa_stroke_close(Stroker* s);
|
||||
VertexBuffer aa_stroke_finish(Stroker* s);
|
||||
VertexBuffer aa_stroke_filled_circle(float cx, float cy, float radius,
|
||||
OutputVertex* output_ptr = nullptr,
|
||||
size_t output_capacity = 0);
|
||||
void aa_stroke_vertex_buffer_release(VertexBuffer vb);
|
||||
void aa_stroke_release(Stroker* s);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user