Merge "Draw textShadow always first." into nyc-dev

This commit is contained in:
Sergei Vasilinetc
2016-05-11 21:34:18 +00:00
committed by Android (Google) Code Review
2 changed files with 57 additions and 12 deletions

View File

@@ -194,8 +194,12 @@ void BakedOpDispatcher::onMergedPatchOps(BakedOpRenderer& renderer,
renderer.renderGlop(nullptr, clip, glop);
}
static void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRenderer,
static void renderTextShadow(BakedOpRenderer& renderer,
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);
PaintUtils::TextShadow textShadow;
@@ -258,15 +262,9 @@ enum class TextRenderType {
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) {
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 y = op.y;
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,
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);
const ClipBase* clip = opList.clipSideFlags ? &renderTargetClip : nullptr;
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));
TextRenderType renderType = (i + 1 == opList.count)
? 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) {
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) {

View File

@@ -19,6 +19,9 @@
#include <RecordedOp.h>
#include <BakedOpDispatcher.h>
#include <BakedOpRenderer.h>
#include <FrameBuilder.h>
#include <SkBlurDrawLooper.h>
#include <hwui/Paint.h>
#include <tests/common/TestUtils.h>
#include <SkDashPathEffect.h>
@@ -26,6 +29,7 @@
using namespace android::uirenderer;
static BakedOpRenderer::LightInfo sLightInfo;
const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50};
static Rect sBaseClip(100, 100);
class ValidatingBakedOpRenderer : public BakedOpRenderer {
@@ -45,7 +49,7 @@ private:
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,
std::function<void(const Glop& glop)> glopVerifier) {
@@ -67,7 +71,7 @@ static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, R
[](BakedOpRenderer& renderer, const BakedOpState& 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
unmergedReceivers[op->opId](renderer, *state);
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);
EXPECT_EQ(TransformFlags::OffsetByFudgeFactor, getGlopTransformFlags(renderThread, &linesOp))
<< "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";
}