Merge "Add partial damage support to new draw path"
This commit is contained in:
@@ -212,10 +212,11 @@ OpReorderer::OpReorderer()
|
||||
: mCanvasState(sNullClient) {
|
||||
}
|
||||
|
||||
void OpReorderer::defer(int viewportWidth, int viewportHeight,
|
||||
void OpReorderer::defer(const SkRect& clip, int viewportWidth, int viewportHeight,
|
||||
const std::vector< sp<RenderNode> >& nodes) {
|
||||
mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
|
||||
0, 0, viewportWidth, viewportHeight, Vector3());
|
||||
clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
|
||||
Vector3());
|
||||
for (const sp<RenderNode>& node : nodes) {
|
||||
if (node->nothingToDraw()) continue;
|
||||
|
||||
@@ -325,7 +326,7 @@ void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) {
|
||||
// if no target, merging ops still interate to find similar batch to insert after
|
||||
void OpReorderer::locateInsertIndex(int batchId, const Rect& clippedBounds,
|
||||
BatchBase** targetBatch, size_t* insertBatchIndex) const {
|
||||
for (size_t i = mBatches.size() - 1; i >= mEarliestBatchIndex; i--) {
|
||||
for (int i = mBatches.size() - 1; i >= mEarliestBatchIndex; i--) {
|
||||
BatchBase* overBatch = mBatches[i];
|
||||
|
||||
if (overBatch == *targetBatch) break;
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
struct SkRect;
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
@@ -57,7 +59,8 @@ public:
|
||||
OpReorderer();
|
||||
|
||||
// TODO: not final, just presented this way for simplicity. Layers too?
|
||||
void defer(int viewportWidth, int viewportHeight, const std::vector< sp<RenderNode> >& nodes);
|
||||
void defer(const SkRect& clip, int viewportWidth, int viewportHeight,
|
||||
const std::vector< sp<RenderNode> >& nodes);
|
||||
|
||||
void defer(int viewportWidth, int viewportHeight,
|
||||
const std::vector<DisplayListData::Chunk>& chunks, const std::vector<RecordedOp*>& ops);
|
||||
@@ -133,7 +136,7 @@ private:
|
||||
// contains ResolvedOps and Batches
|
||||
LinearAllocator mAllocator;
|
||||
|
||||
size_t mEarliestBatchIndex = 0;
|
||||
int mEarliestBatchIndex = 0;
|
||||
};
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
@@ -266,11 +266,11 @@ void CanvasContext::draw() {
|
||||
|
||||
Frame frame = mEglManager.beginFrame(mEglSurface);
|
||||
|
||||
#if !HWUI_NEW_OPS
|
||||
if (frame.width() != mCanvas->getViewportWidth()
|
||||
|| frame.height() != mCanvas->getViewportHeight()) {
|
||||
if (frame.width() != lastFrameWidth || frame.height() != lastFrameHeight) {
|
||||
// can't rely on prior content of window if viewport size changes
|
||||
dirty.setEmpty();
|
||||
lastFrameWidth = frame.width();
|
||||
lastFrameHeight = frame.height();
|
||||
} else if (mHaveNewSurface || frame.bufferAge() == 0) {
|
||||
// New surface needs a full draw
|
||||
dirty.setEmpty();
|
||||
@@ -316,6 +316,18 @@ void CanvasContext::draw() {
|
||||
mDamageHistory.next() = screenDirty;
|
||||
|
||||
mEglManager.damageFrame(frame, dirty);
|
||||
|
||||
#if HWUI_NEW_OPS
|
||||
OpReorderer reorderer;
|
||||
reorderer.defer(dirty, frame.width(), frame.height(), mRenderNodes);
|
||||
BakedOpRenderer::Info info(Caches::getInstance(), mRenderThread.renderState(),
|
||||
frame.width(), frame.height(), mOpaque);
|
||||
// TODO: profiler().draw(mCanvas);
|
||||
reorderer.replayBakedOps<BakedOpRenderer>(&info);
|
||||
|
||||
bool drew = info.didDraw;
|
||||
|
||||
#else
|
||||
mCanvas->prepareDirty(frame.width(), frame.height(),
|
||||
dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom, mOpaque);
|
||||
|
||||
@@ -426,20 +438,10 @@ void CanvasContext::draw() {
|
||||
profiler().draw(mCanvas);
|
||||
|
||||
bool drew = mCanvas->finish();
|
||||
|
||||
#endif
|
||||
// Even if we decided to cancel the frame, from the perspective of jank
|
||||
// metrics the frame was swapped at this point
|
||||
mCurrentFrameInfo->markSwapBuffers();
|
||||
#else
|
||||
OpReorderer reorderer;
|
||||
reorderer.defer(frame.width(), frame.height(), mRenderNodes);
|
||||
BakedOpRenderer::Info info(Caches::getInstance(), mRenderThread.renderState(),
|
||||
frame.width(), frame.height(), mOpaque);
|
||||
reorderer.replayBakedOps<BakedOpRenderer>(&info);
|
||||
|
||||
bool drew = info.didDraw;
|
||||
SkRect screenDirty = SkRect::MakeWH(frame.width(), frame.height());
|
||||
#endif
|
||||
|
||||
if (drew) {
|
||||
if (CC_UNLIKELY(!mEglManager.swapBuffers(frame, screenDirty))) {
|
||||
|
||||
@@ -141,6 +141,9 @@ private:
|
||||
|
||||
void freePrefetechedLayers();
|
||||
|
||||
int lastFrameWidth = 0;
|
||||
int lastFrameHeight = 0;
|
||||
|
||||
RenderThread& mRenderThread;
|
||||
EglManager& mEglManager;
|
||||
sp<ANativeWindow> mNativeWindow;
|
||||
|
||||
@@ -50,9 +50,7 @@ public:
|
||||
};
|
||||
TEST(OpReorderer, simple) {
|
||||
auto dld = TestUtils::createDLD<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.setInfo(SkImageInfo::MakeUnknown(25, 25));
|
||||
|
||||
SkBitmap bitmap = TestUtils::createSkBitmap(25, 25);
|
||||
canvas.drawRect(0, 0, 100, 200, SkPaint());
|
||||
canvas.drawBitmap(bitmap, 10, 10, nullptr);
|
||||
});
|
||||
@@ -81,8 +79,7 @@ public:
|
||||
};
|
||||
TEST(OpReorderer, simpleBatching) {
|
||||
auto dld = TestUtils::createDLD<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.setInfo(SkImageInfo::MakeUnknown(10, 10));
|
||||
SkBitmap bitmap = TestUtils::createSkBitmap(10, 10);
|
||||
|
||||
// Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
|
||||
// Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
|
||||
@@ -134,14 +131,14 @@ TEST(OpReorderer, renderNode) {
|
||||
|
||||
RenderNode* childPtr = child.get();
|
||||
sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [childPtr](RecordingCanvas& canvas) {
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorDKGRAY);
|
||||
canvas.drawRect(0, 0, 200, 200, paint);
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorDKGRAY);
|
||||
canvas.drawRect(0, 0, 200, 200, paint);
|
||||
|
||||
canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
|
||||
canvas.translate(40, 40);
|
||||
canvas.drawRenderNode(childPtr);
|
||||
canvas.restore();
|
||||
canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
|
||||
canvas.translate(40, 40);
|
||||
canvas.drawRenderNode(childPtr);
|
||||
canvas.restore();
|
||||
});
|
||||
|
||||
TestUtils::syncNodePropertiesAndDisplayList(child);
|
||||
@@ -151,11 +148,42 @@ TEST(OpReorderer, renderNode) {
|
||||
nodes.push_back(parent.get());
|
||||
|
||||
OpReorderer reorderer;
|
||||
reorderer.defer(200, 200, nodes);
|
||||
reorderer.defer(SkRect::MakeWH(200, 200), 200, 200, nodes);
|
||||
|
||||
Info info;
|
||||
reorderer.replayBakedOps<RenderNodeReceiver>(&info);
|
||||
}
|
||||
|
||||
class ClippedReceiver {
|
||||
public:
|
||||
static void onBitmapOp(Info* info, const BitmapOp& op, const BakedOpState& state) {
|
||||
EXPECT_EQ(0, info->index++);
|
||||
EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clippedBounds);
|
||||
EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clipRect);
|
||||
EXPECT_TRUE(state.computedState.transform.isIdentity());
|
||||
}
|
||||
UNSUPPORTED_OP(Info, RectOp)
|
||||
UNSUPPORTED_OP(Info, RenderNodeOp)
|
||||
UNSUPPORTED_OP(Info, SimpleRectsOp)
|
||||
static void startFrame(Info& info) {}
|
||||
static void endFrame(Info& info) {}
|
||||
};
|
||||
TEST(OpReorderer, clipped) {
|
||||
sp<RenderNode> node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [](RecordingCanvas& canvas) {
|
||||
SkBitmap bitmap = TestUtils::createSkBitmap(200, 200);
|
||||
canvas.drawBitmap(bitmap, 0, 0, nullptr);
|
||||
});
|
||||
TestUtils::syncNodePropertiesAndDisplayList(node);
|
||||
std::vector< sp<RenderNode> > nodes;
|
||||
nodes.push_back(node.get());
|
||||
|
||||
OpReorderer reorderer;
|
||||
reorderer.defer(SkRect::MakeLTRB(10, 20, 30, 40), // clip to small area, should see in receiver
|
||||
200, 200, nodes);
|
||||
|
||||
Info info;
|
||||
reorderer.replayBakedOps<ClippedReceiver>(&info);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,12 @@ public:
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
static SkBitmap createSkBitmap(int width, int height) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
template<class CanvasType>
|
||||
static std::unique_ptr<DisplayListData> createDLD(int width, int height,
|
||||
std::function<void(CanvasType& canvas)> canvasCallback) {
|
||||
|
||||
Reference in New Issue
Block a user