зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1341101 part 3 - Support building WR gradients in nsCSSGradientRenderer r=mattwoodrow
MozReview-Commit-ID: HLSmseHj5Si --HG-- extra : rebase_source : b8e39ba51c6ab28a2c9ed7b694e5098e50bf022c
This commit is contained in:
Родитель
6e1c6e32b8
Коммит
cfc9025674
|
@ -162,6 +162,61 @@ static inline WrColor ToWrColor(const gfx::Color& color)
|
|||
return c;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrPoint ToWrPoint(const gfx::PointTyped<T>& point)
|
||||
{
|
||||
WrPoint p;
|
||||
p.x = point.x;
|
||||
p.y = point.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrPoint ToWrPoint(const gfx::IntPointTyped<T>& point)
|
||||
{
|
||||
return ToWrPoint(IntPointToPoint(point));
|
||||
}
|
||||
|
||||
static inline WrPoint ToWrPoint(const gfx::Point& point)
|
||||
{
|
||||
WrPoint p;
|
||||
p.x = point.x;
|
||||
p.y = point.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrRect ToWrRect(const gfx::RectTyped<T>& rect)
|
||||
{
|
||||
WrRect r;
|
||||
r.x = rect.x;
|
||||
r.y = rect.y;
|
||||
r.width = rect.width;
|
||||
r.height = rect.height;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrRect ToWrRect(const gfx::IntRectTyped<T>& rect)
|
||||
{
|
||||
return ToWrRect(IntRectToRect(rect));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrSize ToWrSize(const gfx::SizeTyped<T>& size)
|
||||
{
|
||||
WrSize ls;
|
||||
ls.width = size.width;
|
||||
ls.height = size.height;
|
||||
return ls;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrSize ToWrSize(const gfx::IntSizeTyped<T>& size)
|
||||
{
|
||||
return ToWrSize(IntSizeToSize(size));
|
||||
}
|
||||
|
||||
static inline WrBorderStyle ToWrBorderStyle(const uint8_t& style)
|
||||
{
|
||||
switch (style) {
|
||||
|
@ -199,22 +254,6 @@ static inline WrBorderSide ToWrBorderSide(const gfx::Color& color, const uint8_t
|
|||
return bs;
|
||||
}
|
||||
|
||||
static inline WrPoint ToWrPoint(const LayerPoint point)
|
||||
{
|
||||
WrPoint lp;
|
||||
lp.x = point.x;
|
||||
lp.y = point.y;
|
||||
return lp;
|
||||
}
|
||||
|
||||
static inline WrSize ToWrSize(const LayerSize size)
|
||||
{
|
||||
WrSize ls;
|
||||
ls.width = size.width;
|
||||
ls.height = size.height;
|
||||
return ls;
|
||||
}
|
||||
|
||||
static inline WrBorderRadius ToWrUniformBorderRadius(const LayerSize& aSize)
|
||||
{
|
||||
WrBorderRadius br;
|
||||
|
@ -294,23 +333,6 @@ static inline WrRepeatMode ToWrRepeatMode(uint8_t repeatMode)
|
|||
return WrRepeatMode::Stretch;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrRect ToWrRect(const gfx::RectTyped<T>& rect)
|
||||
{
|
||||
WrRect r;
|
||||
r.x = rect.x;
|
||||
r.y = rect.y;
|
||||
r.width = rect.width;
|
||||
r.height = rect.height;
|
||||
return r;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrRect ToWrRect(const gfx::IntRectTyped<T>& rect)
|
||||
{
|
||||
return ToWrRect(IntRectToRect(rect));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrComplexClipRegion ToWrComplexClipRegion(const gfx::RectTyped<T>& rect,
|
||||
const LayerSize& size)
|
||||
|
@ -321,14 +343,6 @@ static inline WrComplexClipRegion ToWrComplexClipRegion(const gfx::RectTyped<T>&
|
|||
return complex_clip;
|
||||
}
|
||||
|
||||
static inline WrPoint ToWrPoint(const gfx::Point& point)
|
||||
{
|
||||
WrPoint p;
|
||||
p.x = point.x;
|
||||
p.y = point.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline WrExternalImageId ToWrExternalImageId(uint64_t aID)
|
||||
{
|
||||
WrExternalImageId id;
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
#include "gfxUtils.h"
|
||||
#include "gfxGradientCache.h"
|
||||
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "Units.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
|
@ -1003,4 +1008,84 @@ nsCSSGradientRenderer::Paint(gfxContext& aContext,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSGradientRenderer::BuildWebRenderDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
float aOpacity)
|
||||
{
|
||||
bool isRepeat = mGradient->mRepeating || mForceRepeatToCoverTiles;
|
||||
WrGradientExtendMode extendMode = isRepeat ? WrGradientExtendMode::Repeat : WrGradientExtendMode::Clamp;
|
||||
|
||||
nsTArray<WrGradientStop> stops(mStops.Length());
|
||||
stops.SetLength(mStops.Length());
|
||||
for(uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
stops[i].color.r = mStops[i].mColor.r;
|
||||
stops[i].color.g = mStops[i].mColor.g;
|
||||
stops[i].color.b = mStops[i].mColor.b;
|
||||
stops[i].color.a = mStops[i].mColor.a * aOpacity;
|
||||
stops[i].offset = mStops[i].mPosition;
|
||||
}
|
||||
|
||||
double firstStop = mStops[0].mPosition;
|
||||
double lastStop = mStops[mStops.Length() - 1].mPosition;
|
||||
|
||||
LayoutDevicePoint lineStart = LayoutDevicePoint(mLineStart.x, mLineStart.y);
|
||||
LayoutDevicePoint lineEnd = LayoutDevicePoint(mLineEnd.x, mLineEnd.y);
|
||||
|
||||
// Do a naive tiling of the gradient by making multiple display items
|
||||
// TODO: this should be done on the WebRender side eventually
|
||||
|
||||
nscoord appUnitsPerDevPixel = mPresContext->AppUnitsPerDevPixel();
|
||||
LayoutDeviceRect firstTileBounds = LayoutDevicePixel::FromAppUnits(mDest, appUnitsPerDevPixel);
|
||||
LayoutDeviceRect clipBounds = LayoutDevicePixel::FromAppUnits(mFillArea, appUnitsPerDevPixel);
|
||||
|
||||
// Make the units relative to the parent stacking context
|
||||
firstTileBounds = LayoutDeviceRect::FromUnknownRect(aLayer->RelativeToParent(firstTileBounds.ToUnknownRect()));
|
||||
clipBounds = LayoutDeviceRect::FromUnknownRect(aLayer->RelativeToParent(clipBounds.ToUnknownRect()));
|
||||
|
||||
float xStart = 0;
|
||||
float yStart = 0;
|
||||
float xEnd = (mFillArea.XMost() - mDest.X()) / appUnitsPerDevPixel;
|
||||
float yEnd = (mFillArea.YMost() - mDest.Y()) / appUnitsPerDevPixel;
|
||||
|
||||
float stepX = mRepeatSize.width / appUnitsPerDevPixel;
|
||||
float stepY = mRepeatSize.height / appUnitsPerDevPixel;
|
||||
|
||||
for (float y = yStart; y < yEnd; y += stepY) {
|
||||
for (float x = xStart; x < xEnd; x += stepX) {
|
||||
LayoutDevicePoint tileOffset = firstTileBounds.TopLeft() + LayoutDevicePoint(x, y);
|
||||
LayoutDeviceRect tileRect = LayoutDeviceRect(tileOffset, firstTileBounds.Size());
|
||||
|
||||
if (mGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
|
||||
LayoutDevicePoint relativeGradientStart = lineStart + tileOffset;
|
||||
LayoutDevicePoint relativeGradientEnd = lineEnd + tileOffset;
|
||||
|
||||
aBuilder.PushLinearGradient(
|
||||
mozilla::wr::ToWrRect(tileRect),
|
||||
aBuilder.BuildClipRegion(mozilla::wr::ToWrRect(clipBounds)),
|
||||
mozilla::wr::ToWrPoint(relativeGradientStart),
|
||||
mozilla::wr::ToWrPoint(relativeGradientEnd),
|
||||
stops,
|
||||
extendMode);
|
||||
} else {
|
||||
LayoutDevicePoint relativeGradientCenter = lineStart + tileOffset;
|
||||
|
||||
// TODO: ellipse gradients
|
||||
double innerRadius = mRadiusX * firstStop;
|
||||
double outerRadius = mRadiusX * lastStop;
|
||||
|
||||
aBuilder.PushRadialGradient(
|
||||
mozilla::wr::ToWrRect(tileRect),
|
||||
aBuilder.BuildClipRegion(mozilla::wr::ToWrRect(clipBounds)),
|
||||
mozilla::wr::ToWrPoint(relativeGradientCenter),
|
||||
mozilla::wr::ToWrPoint(relativeGradientCenter),
|
||||
innerRadius,
|
||||
outerRadius,
|
||||
stops,
|
||||
extendMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -13,6 +13,14 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
class WebRenderDisplayItemLayer;
|
||||
} // namespace layers
|
||||
|
||||
namespace wr {
|
||||
class DisplayListBuilder;
|
||||
}
|
||||
|
||||
// A resolved color stop, with a specific position along the gradient line and
|
||||
// a color.
|
||||
struct ColorStop {
|
||||
|
@ -48,6 +56,10 @@ public:
|
|||
const nsRect& aDirtyRect,
|
||||
float aOpacity = 1.0);
|
||||
|
||||
void BuildWebRenderDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
float aOpacity = 1.0);
|
||||
|
||||
private:
|
||||
nsCSSGradientRenderer() {}
|
||||
|
||||
|
@ -60,7 +72,7 @@ private:
|
|||
nsSize mRepeatSize;
|
||||
nsTArray<ColorStop> mStops;
|
||||
gfxPoint mLineStart, mLineEnd;
|
||||
double mRadiusX, mRadiusY; // for radial gradients only
|
||||
double mRadiusX, mRadiusY;
|
||||
bool mForceRepeatToCoverTiles;
|
||||
bool mForceRepeatToCoverTilesFlip;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче