Merge "Draw textShadow always first." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
45d6e79565
@@ -194,8 +194,12 @@ void BakedOpDispatcher::onMergedPatchOps(BakedOpRenderer& renderer,
|
|||||||
renderer.renderGlop(nullptr, clip, glop);
|
renderer.renderGlop(nullptr, clip, glop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRenderer,
|
static void renderTextShadow(BakedOpRenderer& renderer,
|
||||||
const TextOp& op, const BakedOpState& textOpState) {
|
const TextOp& op, const BakedOpState& textOpState) {
|
||||||
|
if (CC_LIKELY(!PaintUtils::hasTextShadow(op.paint))) return;
|
||||||
|
|
||||||
|
FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
|
||||||
|
fontRenderer.setFont(op.paint, SkMatrix::I());
|
||||||
renderer.caches().textureState().activateTexture(0);
|
renderer.caches().textureState().activateTexture(0);
|
||||||
|
|
||||||
PaintUtils::TextShadow textShadow;
|
PaintUtils::TextShadow textShadow;
|
||||||
@@ -258,15 +262,9 @@ enum class TextRenderType {
|
|||||||
Flush
|
Flush
|
||||||
};
|
};
|
||||||
|
|
||||||
static void renderTextOp(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state,
|
static void renderText(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state,
|
||||||
const ClipBase* renderClip, TextRenderType renderType) {
|
const ClipBase* renderClip, TextRenderType renderType) {
|
||||||
FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
|
FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
|
||||||
|
|
||||||
if (CC_UNLIKELY(PaintUtils::hasTextShadow(op.paint))) {
|
|
||||||
fontRenderer.setFont(op.paint, SkMatrix::I());
|
|
||||||
renderTextShadow(renderer, fontRenderer, op, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
float x = op.x;
|
float x = op.x;
|
||||||
float y = op.y;
|
float y = op.y;
|
||||||
const Matrix4& transform = state.computedState.transform;
|
const Matrix4& transform = state.computedState.transform;
|
||||||
@@ -321,6 +319,12 @@ static void renderTextOp(BakedOpRenderer& renderer, const TextOp& op, const Bake
|
|||||||
|
|
||||||
void BakedOpDispatcher::onMergedTextOps(BakedOpRenderer& renderer,
|
void BakedOpDispatcher::onMergedTextOps(BakedOpRenderer& renderer,
|
||||||
const MergedBakedOpList& opList) {
|
const MergedBakedOpList& opList) {
|
||||||
|
for (size_t i = 0; i < opList.count; i++) {
|
||||||
|
const BakedOpState& state = *(opList.states[i]);
|
||||||
|
const TextOp& op = *(static_cast<const TextOp*>(state.op));
|
||||||
|
renderTextShadow(renderer, op, state);
|
||||||
|
}
|
||||||
|
|
||||||
ClipRect renderTargetClip(opList.clip);
|
ClipRect renderTargetClip(opList.clip);
|
||||||
const ClipBase* clip = opList.clipSideFlags ? &renderTargetClip : nullptr;
|
const ClipBase* clip = opList.clipSideFlags ? &renderTargetClip : nullptr;
|
||||||
for (size_t i = 0; i < opList.count; i++) {
|
for (size_t i = 0; i < opList.count; i++) {
|
||||||
@@ -328,7 +332,7 @@ void BakedOpDispatcher::onMergedTextOps(BakedOpRenderer& renderer,
|
|||||||
const TextOp& op = *(static_cast<const TextOp*>(state.op));
|
const TextOp& op = *(static_cast<const TextOp*>(state.op));
|
||||||
TextRenderType renderType = (i + 1 == opList.count)
|
TextRenderType renderType = (i + 1 == opList.count)
|
||||||
? TextRenderType::Flush : TextRenderType::Defer;
|
? TextRenderType::Flush : TextRenderType::Defer;
|
||||||
renderTextOp(renderer, op, state, clip, renderType);
|
renderText(renderer, op, state, clip, renderType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,7 +744,8 @@ void BakedOpDispatcher::onSimpleRectsOp(BakedOpRenderer& renderer, const SimpleR
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BakedOpDispatcher::onTextOp(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state) {
|
void BakedOpDispatcher::onTextOp(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state) {
|
||||||
renderTextOp(renderer, op, state, state.computedState.getClipIfNeeded(), TextRenderType::Flush);
|
renderTextShadow(renderer, op, state);
|
||||||
|
renderText(renderer, op, state, state.computedState.getClipIfNeeded(), TextRenderType::Flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BakedOpDispatcher::onTextOnPathOp(BakedOpRenderer& renderer, const TextOnPathOp& op, const BakedOpState& state) {
|
void BakedOpDispatcher::onTextOnPathOp(BakedOpRenderer& renderer, const TextOnPathOp& op, const BakedOpState& state) {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
#include <RecordedOp.h>
|
#include <RecordedOp.h>
|
||||||
#include <BakedOpDispatcher.h>
|
#include <BakedOpDispatcher.h>
|
||||||
#include <BakedOpRenderer.h>
|
#include <BakedOpRenderer.h>
|
||||||
|
#include <FrameBuilder.h>
|
||||||
|
#include <SkBlurDrawLooper.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
#include <tests/common/TestUtils.h>
|
#include <tests/common/TestUtils.h>
|
||||||
|
|
||||||
#include <SkDashPathEffect.h>
|
#include <SkDashPathEffect.h>
|
||||||
@@ -26,6 +29,7 @@
|
|||||||
using namespace android::uirenderer;
|
using namespace android::uirenderer;
|
||||||
|
|
||||||
static BakedOpRenderer::LightInfo sLightInfo;
|
static BakedOpRenderer::LightInfo sLightInfo;
|
||||||
|
const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50};
|
||||||
static Rect sBaseClip(100, 100);
|
static Rect sBaseClip(100, 100);
|
||||||
|
|
||||||
class ValidatingBakedOpRenderer : public BakedOpRenderer {
|
class ValidatingBakedOpRenderer : public BakedOpRenderer {
|
||||||
@@ -45,7 +49,7 @@ private:
|
|||||||
std::function<void(const Glop& glop)> mValidator;
|
std::function<void(const Glop& glop)> mValidator;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*BakedOpReceiver)(BakedOpRenderer&, const BakedOpState&);
|
typedef void (*TestBakedOpReceiver)(BakedOpRenderer&, const BakedOpState&);
|
||||||
|
|
||||||
static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op,
|
static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op,
|
||||||
std::function<void(const Glop& glop)> glopVerifier) {
|
std::function<void(const Glop& glop)> glopVerifier) {
|
||||||
@@ -67,7 +71,7 @@ static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, R
|
|||||||
[](BakedOpRenderer& renderer, const BakedOpState& state) { \
|
[](BakedOpRenderer& renderer, const BakedOpState& state) { \
|
||||||
BakedOpDispatcher::on##Type(renderer, static_cast<const Type&>(*(state.op)), state); \
|
BakedOpDispatcher::on##Type(renderer, static_cast<const Type&>(*(state.op)), state); \
|
||||||
},
|
},
|
||||||
static BakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X);
|
static TestBakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X);
|
||||||
#undef X
|
#undef X
|
||||||
unmergedReceivers[op->opId](renderer, *state);
|
unmergedReceivers[op->opId](renderer, *state);
|
||||||
ASSERT_EQ(1, glopCount) << "Exactly one Glop expected";
|
ASSERT_EQ(1, glopCount) << "Exactly one Glop expected";
|
||||||
@@ -154,4 +158,40 @@ RENDERTHREAD_TEST(BakedOpDispatcher, offsetFlags) {
|
|||||||
LinesOp linesOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4);
|
LinesOp linesOp(bounds, Matrix4::identity(), nullptr, &paint, points, 4);
|
||||||
EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &linesOp))
|
EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &linesOp))
|
||||||
<< "Expect an offset for non-AA lines.";
|
<< "Expect an offset for non-AA lines.";
|
||||||
|
}
|
||||||
|
|
||||||
|
RENDERTHREAD_TEST(BakedOpDispatcher, renderTextWithShadow) {
|
||||||
|
auto node = TestUtils::createNode(0, 0, 100, 100,
|
||||||
|
[](RenderProperties& props, TestCanvas& canvas) {
|
||||||
|
|
||||||
|
android::Paint shadowPaint;
|
||||||
|
shadowPaint.setColor(SK_ColorRED);
|
||||||
|
|
||||||
|
SkScalar sigma = Blur::convertRadiusToSigma(5);
|
||||||
|
shadowPaint.setLooper(SkBlurDrawLooper::Create(SK_ColorWHITE, sigma, 3, 3))->unref();
|
||||||
|
|
||||||
|
TestUtils::drawUtf8ToCanvas(&canvas, "A", shadowPaint, 25, 25);
|
||||||
|
TestUtils::drawUtf8ToCanvas(&canvas, "B", shadowPaint, 50, 50);
|
||||||
|
});
|
||||||
|
|
||||||
|
int glopCount = 0;
|
||||||
|
auto glopReceiver = [&glopCount] (const Glop& glop) {
|
||||||
|
if (glopCount < 2) {
|
||||||
|
// two white shadows
|
||||||
|
EXPECT_EQ(FloatColor({1, 1, 1, 1}), glop.fill.color);
|
||||||
|
} else {
|
||||||
|
// two text draws merged into one, drawn after both shadows
|
||||||
|
EXPECT_EQ(FloatColor({1, 0, 0, 1}), glop.fill.color);
|
||||||
|
}
|
||||||
|
glopCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver);
|
||||||
|
|
||||||
|
FrameBuilder frameBuilder(SkRect::MakeWH(100, 100), 100, 100,
|
||||||
|
sLightGeometry, Caches::getInstance());
|
||||||
|
frameBuilder.deferRenderNode(*TestUtils::getSyncedNode(node));
|
||||||
|
|
||||||
|
frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
|
||||||
|
ASSERT_EQ(3, glopCount) << "Exactly three glops expected";
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user