Merge "Fix a translate issue with saveLayer" into nyc-dev
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user