Bug 1323797 - Add compositor support for triangle layers (for BasicCompositor backend) - Part 3: Implement DrawPolygon() with Paths r=mattwoodrow

MozReview-Commit-ID: FjxDlzdhqor

--HG--
extra : rebase_source : 0a0737cec7bc2d5cb7df264d7a9043c895b47275
This commit is contained in:
Miko Mynttinen 2017-01-10 20:48:44 +02:00
parent 139ddef384
commit 9c41859a25
6 changed files with 243 additions and 16 deletions

View File

@ -356,15 +356,100 @@ BasicCompositor::SupportsEffect(EffectTypes aEffect)
return aEffect != EffectTypes::YCBCR && aEffect != EffectTypes::COMPONENT_ALPHA;
}
bool
BasicCompositor::SupportsLayerGeometry() const
{
return gfxPrefs::BasicLayerGeometry();
}
static RefPtr<gfx::Path>
BuildPathFromPolygon(const RefPtr<DrawTarget>& aDT,
const gfx::Polygon& aPolygon)
{
RefPtr<PathBuilder> pathBuilder = aDT->CreatePathBuilder();
const nsTArray<Point4D>& points = aPolygon.GetPoints();
pathBuilder->MoveTo(points[0].As2DPoint());
for (size_t i = 1; i < points.Length(); ++i) {
pathBuilder->LineTo(points[i].As2DPoint());
}
pathBuilder->Close();
return pathBuilder->Finish();
}
static void
DrawSurfaceWithTextureCoords(DrawTarget *aDest,
DrawSurface(gfx::DrawTarget* aDest,
const gfx::Rect& aDestRect,
const gfx::Rect& /* aClipRect */,
const gfx::Color& aColor,
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform)
{
FillRectWithMask(aDest, aDestRect, aColor,
aOptions, aMask, aMaskTransform);
}
static void
DrawSurface(gfx::DrawTarget* aDest,
const gfx::Polygon& aPolygon,
const gfx::Rect& aClipRect,
const gfx::Color& aColor,
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform)
{
RefPtr<Path> path = BuildPathFromPolygon(aDest, aPolygon);
FillPathWithMask(aDest, path, aClipRect, aColor,
aOptions, aMask, aMaskTransform);
}
static void
DrawTextureSurface(gfx::DrawTarget* aDest,
const gfx::Rect& aDestRect,
const gfx::Rect& /* aClipRect */,
gfx::SourceSurface* aSource,
gfx::SamplingFilter aSamplingFilter,
const gfx::DrawOptions& aOptions,
ExtendMode aExtendMode,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform,
const Matrix* aSurfaceTransform)
{
FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
aExtendMode, aMask, aMaskTransform, aSurfaceTransform);
}
static void
DrawTextureSurface(gfx::DrawTarget* aDest,
const gfx::Polygon& aPolygon,
const gfx::Rect& aClipRect,
gfx::SourceSurface* aSource,
gfx::SamplingFilter aSamplingFilter,
const gfx::DrawOptions& aOptions,
ExtendMode aExtendMode,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform,
const Matrix* aSurfaceTransform)
{
RefPtr<Path> path = BuildPathFromPolygon(aDest, aPolygon);
FillPathWithMask(aDest, path, aClipRect, aSource, aSamplingFilter, aOptions,
aExtendMode, aMask, aMaskTransform, aSurfaceTransform);
}
template<typename Geometry>
static void
DrawSurfaceWithTextureCoords(gfx::DrawTarget* aDest,
const Geometry& aGeometry,
const gfx::Rect& aDestRect,
SourceSurface *aSource,
gfx::SourceSurface* aSource,
const gfx::Rect& aTextureCoords,
gfx::SamplingFilter aSamplingFilter,
const DrawOptions& aOptions,
SourceSurface *aMask,
const Matrix* aMaskTransform)
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform)
{
if (!aSource) {
gfxWarning() << "DrawSurfaceWithTextureCoords problem " << gfx::hexa(aSource) << " and " << gfx::hexa(aMask);
@ -392,8 +477,8 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest,
gfx::Rect unitRect(0, 0, 1, 1);
ExtendMode mode = unitRect.Contains(aTextureCoords) ? ExtendMode::CLAMP : ExtendMode::REPEAT;
FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
mode, aMask, aMaskTransform, &matrix);
DrawTextureSurface(aDest, aGeometry, aDestRect, aSource, aSamplingFilter,
aOptions, mode, aMask, aMaskTransform, &matrix);
}
static void
@ -552,6 +637,35 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
DrawGeometry(aRect, aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect, true);
}
void
BasicCompositor::DrawPolygon(const gfx::Polygon& aPolygon,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
DrawGeometry(aPolygon, aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect, false);
}
template<typename Geometry>
void
BasicCompositor::DrawGeometry(const Geometry& aGeometry,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect,
const bool aEnableAA)
{
RefPtr<DrawTarget> buffer = mRenderTarget->mDrawTarget;
@ -613,6 +727,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode;
}
const AntialiasMode aaMode =
aEnableAA ? AntialiasMode::DEFAULT : AntialiasMode::NONE;
DrawOptions drawOptions(aOpacity, blendMode, aaMode);
switch (aEffectChain.mPrimaryEffect->mType) {
case EffectTypes::SOLID_COLOR: {
EffectSolidColor* effectSolidColor =
@ -623,8 +742,8 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
dest->PushClipRect(aRect);
}
FillRectWithMask(dest, aRect, effectSolidColor->mColor,
DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform);
DrawSurface(dest, aGeometry, aRect, effectSolidColor->mColor,
drawOptions, sourceMask, &maskTransform);
if (unboundedOp) {
dest->PopClip();
@ -654,11 +773,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
dest, buffer)) {
// we succeeded in scaling
} else {
DrawSurfaceWithTextureCoords(dest, aRect,
DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
source->GetSurface(dest),
texturedEffect->mTextureCoords,
texturedEffect->mSamplingFilter,
DrawOptions(aOpacity, blendMode),
drawOptions,
sourceMask, &maskTransform);
}
} else if (source) {
@ -670,11 +789,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
// This might be better with a cache, eventually.
RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData);
DrawSurfaceWithTextureCoords(dest, aRect,
DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
premultData,
texturedEffect->mTextureCoords,
texturedEffect->mSamplingFilter,
DrawOptions(aOpacity, blendMode),
drawOptions,
sourceMask, &maskTransform);
}
} else {
@ -694,11 +813,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
= static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get());
RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot();
DrawSurfaceWithTextureCoords(dest, aRect,
DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
sourceSurf,
effectRenderTarget->mTextureCoords,
effectRenderTarget->mSamplingFilter,
DrawOptions(aOpacity, blendMode),
drawOptions,
sourceMask, &maskTransform);
break;
}

View File

@ -9,6 +9,8 @@
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Triangle.h"
#include "mozilla/gfx/Polygon.h"
namespace mozilla {
namespace layers {
@ -80,6 +82,8 @@ public:
virtual bool SupportsEffect(EffectTypes aEffect) override;
bool SupportsLayerGeometry() const override;
virtual void SetRenderTarget(CompositingRenderTarget *aSource) override
{
mRenderTarget = static_cast<BasicCompositingRenderTarget*>(aSource);
@ -111,7 +115,7 @@ public:
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override { return true; }
virtual int32_t GetMaxTextureSize() const override;
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override { }
virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) override {
}
@ -136,6 +140,24 @@ public:
private:
template<typename Geometry>
void DrawGeometry(const Geometry& aGeometry,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect,
const bool aEnableAA);
virtual void DrawPolygon(const gfx::Polygon& aPolygon,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) override;
void TryToEndRemoteDrawing(bool aForceToEnd = false);
bool NeedsToDeferEndRemoteDrawing();

View File

@ -206,6 +206,68 @@ FillRectWithMask(DrawTarget* aDT,
ExtendMode::CLAMP);
}
void
FillPathWithMask(DrawTarget* aDT,
const Path* aPath,
const Rect& aClipRect,
const Color& aColor,
const DrawOptions& aOptions,
SourceSurface* aMaskSource,
const Matrix* aMaskTransform)
{
if (aMaskSource && aMaskTransform) {
aDT->PushClipRect(aClipRect);
Matrix oldTransform = aDT->GetTransform();
aDT->SetTransform(*aMaskTransform);
aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
aDT->SetTransform(oldTransform);
aDT->PopClip();
return;
}
aDT->Fill(aPath, ColorPattern(aColor), aOptions);
}
void
FillPathWithMask(DrawTarget* aDT,
const Path* aPath,
const Rect& aClipRect,
SourceSurface* aSurface,
SamplingFilter aSamplingFilter,
const DrawOptions& aOptions,
ExtendMode aExtendMode,
SourceSurface* aMaskSource,
const Matrix* aMaskTransform,
const Matrix* aSurfaceTransform)
{
if (aMaskSource && aMaskTransform) {
aDT->PushClipRect(aClipRect);
Matrix oldTransform = aDT->GetTransform();
Matrix inverseMask = *aMaskTransform;
inverseMask.Invert();
Matrix transform = oldTransform * inverseMask;
if (aSurfaceTransform) {
transform = (*aSurfaceTransform) * transform;
}
SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);
aDT->SetTransform(*aMaskTransform);
aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
aDT->SetTransform(oldTransform);
aDT->PopClip();
return;
}
aDT->Fill(aPath,
SurfacePattern(aSurface, aExtendMode,
aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
aSamplingFilter), aOptions);
}
BasicImplData*
ToData(Layer* aLayer)
{

View File

@ -127,6 +127,26 @@ FillRectWithMask(gfx::DrawTarget* aDT,
const gfx::DrawOptions& aOptions,
Layer* aMaskLayer);
void
FillPathWithMask(gfx::DrawTarget* aDT,
const gfx::Path* aPath,
const gfx::Rect& aClipRect,
const gfx::Color& aColor,
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMaskSource = nullptr,
const gfx::Matrix* aMaskTransform = nullptr);
void
FillPathWithMask(gfx::DrawTarget* aDT,
const gfx::Path* aPath,
const gfx::Rect& aClipRect,
gfx::SourceSurface* aSurface,
gfx::SamplingFilter aSamplingFilter,
const gfx::DrawOptions& aOptions,
gfx::ExtendMode aExtendMode,
gfx::SourceSurface* aMaskSource,
const gfx::Matrix* aMaskTransform,
const gfx::Matrix* aSurfaceTransform);
BasicImplData*
ToData(Layer* aLayer);

View File

@ -527,6 +527,7 @@ private:
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, true);
DECL_GFX_PREF(Live, "layers.draw-mask-debug", DrawMaskLayer, bool, false);
DECL_GFX_PREF(Live, "layers.geometry.opengl.enabled", OGLLayerGeometry, bool, false);
DECL_GFX_PREF(Live, "layers.geometry.basic.enabled", BasicLayerGeometry, bool, false);
DECL_GFX_PREF(Live, "layout.animation.prerender.partial", PartiallyPrerenderAnimatedContent, bool, false);
DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-x", AnimationPrerenderViewportRatioLimitX, float, 1.125f);

View File

@ -610,6 +610,9 @@ pref("layout.event-regions.enabled", false);
// Whether to enable arbitrary layer geometry for OpenGL compositor
pref("layers.geometry.opengl.enabled", true);
// Whether to enable arbitrary layer geometry for Basic compositor
pref("layers.geometry.basic.enabled", true);
// APZ preferences. For documentation/details on what these prefs do, check
// gfx/layers/apz/src/AsyncPanZoomController.cpp.
pref("apz.allow_checkerboarding", true);