Add functor support to new reorderer/renderer
bug:22480459
Change-Id: I95df7e0504f62d254e8ffbd8d65ed5d763080b9c
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 6ba23e9..9e39797 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -518,6 +518,10 @@
renderer.renderGlop(state, glop);
}
+void BakedOpDispatcher::onFunctorOp(BakedOpRenderer& renderer, const FunctorOp& op, const BakedOpState& state) {
+ renderer.renderFunctor(op, state);
+}
+
void BakedOpDispatcher::onLinesOp(BakedOpRenderer& renderer, const LinesOp& op, const BakedOpState& state) {
VertexBuffer buffer;
PathTessellator::tessellateLines(op.points, op.floatCount, op.paint,
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 93a9406..f8282dc 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -128,7 +128,7 @@
return texture;
}
-void BakedOpRenderer::renderGlop(const Rect* dirtyBounds, const Rect* clip, const Glop& glop) {
+void BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const Rect* clip) {
mRenderState.scissor().setEnabled(clip != nullptr);
if (clip) {
mRenderState.scissor().set(clip->left, mRenderTarget.viewportHeight - clip->bottom,
@@ -140,10 +140,31 @@
dirtyBounds->right, dirtyBounds->bottom);
mRenderTarget.offscreenBuffer->region.orSelf(dirty);
}
+}
+
+void BakedOpRenderer::renderGlop(const Rect* dirtyBounds, const Rect* clip, const Glop& glop) {
+ prepareRender(dirtyBounds, clip);
mRenderState.render(glop, mRenderTarget.orthoMatrix);
if (!mRenderTarget.frameBufferId) mHasDrawn = true;
}
+void BakedOpRenderer::renderFunctor(const FunctorOp& op, const BakedOpState& state) {
+ prepareRender(&state.computedState.clippedBounds, &state.computedState.clipRect);
+
+ DrawGlInfo info;
+ auto&& clip = state.computedState.clipRect;
+ info.clipLeft = clip.left;
+ info.clipTop = clip.top;
+ info.clipRight = clip.right;
+ info.clipBottom = clip.bottom;
+ info.isLayer = offscreenRenderTarget();
+ info.width = mRenderTarget.viewportWidth;
+ info.height = mRenderTarget.viewportHeight;
+ state.computedState.transform.copyTo(&info.transform[0]);
+
+ mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info);
+}
+
void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) {
if (mRenderTarget.offscreenBuffer) {
android::Rect dirty(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom);
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index d7600db..f158e8b 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -65,7 +65,7 @@
void endLayer();
Texture* getTexture(const SkBitmap* bitmap);
- const LightInfo& getLightInfo() { return mLightInfo; }
+ const LightInfo& getLightInfo() const { return mLightInfo; }
void renderGlop(const BakedOpState& state, const Glop& glop) {
bool useScissor = state.computedState.clipSideFlags != OpClipSideFlags::None;
@@ -73,14 +73,16 @@
useScissor ? &state.computedState.clipRect : nullptr,
glop);
}
+ void renderFunctor(const FunctorOp& op, const BakedOpState& state);
void renderGlop(const Rect* dirtyBounds, const Rect* clip, const Glop& glop);
bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
void dirtyRenderTarget(const Rect& dirtyRect);
- bool didDraw() { return mHasDrawn; }
+ bool didDraw() const { return mHasDrawn; }
private:
void setViewport(uint32_t width, uint32_t height);
void clearColorBuffer(const Rect& clearRect);
+ void prepareRender(const Rect* dirtyBounds, const Rect* clip);
RenderState& mRenderState;
Caches& mCaches;
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index ec03e83..6d90a42 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -784,6 +784,12 @@
deferOvalOp(*resolvedOp);
}
+void OpReorderer::deferFunctorOp(const FunctorOp& op) {
+ BakedOpState* bakedState = tryBakeOpState(op);
+ if (!bakedState) return; // quick rejected
+ currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::None);
+}
+
void OpReorderer::deferLinesOp(const LinesOp& op) {
batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index cd7a4bb..b58b774 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -49,6 +49,7 @@
U_OP_FN(BitmapMeshOp) \
U_OP_FN(BitmapRectOp) \
U_OP_FN(CirclePropsOp) \
+ U_OP_FN(FunctorOp) \
U_OP_FN(LinesOp) \
U_OP_FN(OvalOp) \
M_OP_FN(PatchOp) \
@@ -195,6 +196,13 @@
const float* radius;
};
+struct FunctorOp : RecordedOp {
+ FunctorOp(BASE_PARAMS_PAINTLESS, Functor* functor)
+ : SUPER_PAINTLESS(FunctorOp)
+ , functor(functor) {}
+ Functor* functor;
+};
+
struct LinesOp : RecordedOp {
LinesOp(BASE_PARAMS, const float* points, const int floatCount)
: SUPER(LinesOp)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index c7b16a1..7f035e5 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -197,8 +197,7 @@
// Clip
bool RecordingCanvas::getClipBounds(SkRect* outRect) const {
- Rect bounds = mState.getLocalClipBounds();
- *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ *outRect = mState.getLocalClipBounds().toSkRect();
return !(outRect->isEmpty());
}
bool RecordingCanvas::quickRejectRect(float left, float top, float right, float bottom) const {
@@ -516,6 +515,7 @@
mState.getRenderTargetClipBounds(),
refPaint(paint), refBitmap(*bitmap)));
}
+
void RecordingCanvas::drawRenderNode(RenderNode* renderNode) {
auto&& stagingProps = renderNode->stagingProperties();
RenderNodeOp* op = new (alloc()) RenderNodeOp(
@@ -536,6 +536,15 @@
}
}
+void RecordingCanvas::callDrawGLFunction(Functor* functor) {
+ mDisplayList->functors.push_back(functor);
+ addOp(new (alloc()) FunctorOp(
+ mState.getRenderTargetClipBounds(), // TODO: explicitly define bounds
+ *(mState.currentSnapshot()->transform),
+ mState.getRenderTargetClipBounds(),
+ functor));
+}
+
size_t RecordingCanvas::addOp(RecordedOp* op) {
// TODO: validate if "addDrawOp" quickrejection logic is useful before adding
int insertIndex = mDisplayList->ops.size();
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 6fbaa8a..49bdba8 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -61,6 +61,9 @@
}
void drawRenderNode(RenderNode* renderNode);
+ // TODO: rename for consistency
+ void callDrawGLFunction(Functor* functor);
+
// ----------------------------------------------------------------------------
// CanvasStateClient interface
// ----------------------------------------------------------------------------