Merge "Fix a translate issue with saveLayer" into nyc-dev

This commit is contained in:
John Reck
2016-05-25 16:27:30 +00:00
committed by Android (Google) Code Review
4 changed files with 49 additions and 1 deletions

View File

@@ -878,11 +878,49 @@ void FrameBuilder::deferEndLayerOp(const EndLayerOp& /* ignored */) {
restoreForLayer();
// saveLayer will clip & translate the draw contents, so we need
// to translate the drawLayer by how much the contents was translated
// TODO: Unify this with beginLayerOp so we don't have to calculate this
// twice
uint32_t layerWidth = (uint32_t) beginLayerOp.unmappedBounds.getWidth();
uint32_t layerHeight = (uint32_t) beginLayerOp.unmappedBounds.getHeight();
auto previous = mCanvasState.currentSnapshot();
Vector3 lightCenter = previous->getRelativeLightCenter();
// Combine all transforms used to present saveLayer content:
// parent content transform * canvas transform * bounds offset
Matrix4 contentTransform(*(previous->transform));
contentTransform.multiply(beginLayerOp.localMatrix);
contentTransform.translate(beginLayerOp.unmappedBounds.left,
beginLayerOp.unmappedBounds.top);
Matrix4 inverseContentTransform;
inverseContentTransform.loadInverse(contentTransform);
// map the light center into layer-relative space
inverseContentTransform.mapPoint3d(lightCenter);
// Clip bounds of temporary layer to parent's clip rect, so:
Rect saveLayerBounds(layerWidth, layerHeight);
// 1) transform Rect(width, height) into parent's space
// note: left/top offsets put in contentTransform above
contentTransform.mapRect(saveLayerBounds);
// 2) intersect with parent's clip
saveLayerBounds.doIntersect(previous->getRenderTargetClip());
// 3) and transform back
inverseContentTransform.mapRect(saveLayerBounds);
saveLayerBounds.doIntersect(Rect(layerWidth, layerHeight));
saveLayerBounds.roundOut();
Matrix4 localMatrix(beginLayerOp.localMatrix);
localMatrix.translate(saveLayerBounds.left, saveLayerBounds.top);
// record the draw operation into the previous layer's list of draw commands
// uses state from the associated beginLayerOp, since it has all the state needed for drawing
LayerOp* drawLayerOp = mAllocator.create_trivial<LayerOp>(
beginLayerOp.unmappedBounds,
beginLayerOp.localMatrix,
localMatrix,
beginLayerOp.localClip,
beginLayerOp.paint,
&(mLayerBuilders[finishedLayerIndex]->offscreenBuffer));

View File

@@ -45,5 +45,9 @@ void OpDumper::dump(const RecordedOp& op, std::ostream& output, int level) {
}
}
const char* OpDumper::opName(const RecordedOp& op) {
return sOpNameLut[op.opId];
}
} // namespace uirenderer
} // namespace android

View File

@@ -26,6 +26,7 @@ struct RecordedOp;
class OpDumper {
public:
static void dump(const RecordedOp& op, std::ostream& output, int level = 0);
static const char* opName(const RecordedOp& op);
};
}; // namespace uirenderer

View File

@@ -2025,6 +2025,7 @@ struct SaveLayerAlphaData {
uint32_t layerHeight = 0;
Rect rectClippedBounds;
Matrix4 rectMatrix;
Matrix4 drawLayerMatrix;
};
/**
* Constructs a view to hit the temporary layer alpha property implementation:
@@ -2060,6 +2061,7 @@ void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData,
}
void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
EXPECT_EQ(3, mIndex++);
mOutData->drawLayerMatrix = state.computedState.transform;
}
void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override {
EXPECT_EQ(4, mIndex++);
@@ -2108,6 +2110,9 @@ RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaClipBig) {
expected.loadTranslate(0, -2000, 0);
EXPECT_MATRIX_APPROX_EQ(expected, observedData.rectMatrix)
<< "expect content to be translated as part of being clipped";
expected.loadTranslate(10, 0, 0);
EXPECT_MATRIX_APPROX_EQ(expected, observedData.drawLayerMatrix)
<< "expect drawLayer to be translated as part of being clipped";
}
RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaRotate) {