Have RT drive window positioning
Bug: 22802885
Change-Id: I6beed5474d3a943b16e9097f7bd61ce3cbd37505
diff --git a/libs/hwui/DamageAccumulator.h b/libs/hwui/DamageAccumulator.h
index e44fc20..250296e 100644
--- a/libs/hwui/DamageAccumulator.h
+++ b/libs/hwui/DamageAccumulator.h
@@ -57,7 +57,7 @@
// Returns the current dirty area, *NOT* transformed by pushed transforms
void peekAtDirty(SkRect* dest) const;
- void computeCurrentTransform(Matrix4* outMatrix) const;
+ ANDROID_API void computeCurrentTransform(Matrix4* outMatrix) const;
void finish(SkRect* totalDirty);
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index d4588ed..bade216 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -381,6 +381,10 @@
bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence(
willHaveFunctor, functorsNeedLayer);
+ if (CC_UNLIKELY(mPositionListener.get())) {
+ mPositionListener->onPositionUpdated(*this, info);
+ }
+
prepareLayer(info, animatorDirtyMask);
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingDisplayListChanges(info);
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 8e4a3df..f248de54 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -209,6 +209,19 @@
OffscreenBuffer** getLayerHandle() { return &mLayer; } // ugh...
#endif
+ class ANDROID_API PositionListener {
+ public:
+ virtual ~PositionListener() {}
+ virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) = 0;
+ };
+
+ // Note this is not thread safe, this needs to be called
+ // before the RenderNode is used for drawing.
+ // RenderNode takes ownership of the pointer
+ ANDROID_API void setPositionListener(PositionListener* listener) {
+ mPositionListener.reset(listener);
+ }
+
private:
typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair;
@@ -317,6 +330,8 @@
// This is *NOT* thread-safe, and should therefore only be tracking
// mDisplayList, not mStagingDisplayList.
uint32_t mParentCount;
+
+ std::unique_ptr<PositionListener> mPositionListener;
}; // class RenderNode
} /* namespace uirenderer */
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index be25516..accd303 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -86,6 +86,12 @@
#endif
ErrorHandler* errorHandler = nullptr;
+ // Frame number for use with synchronized surfaceview position updating
+ int64_t frameNumber = -1;
+ int32_t windowInsetLeft = 0;
+ int32_t windowInsetTop = 0;
+ bool updateWindowPositions = false;
+
struct Out {
bool hasFunctors = false;
// This is only updated if evaluateAnimations is true
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index e7cf3ec..8207bdb 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -96,18 +96,18 @@
}
}
-void CanvasContext::setSurface(ANativeWindow* window) {
+void CanvasContext::setSurface(Surface* surface) {
ATRACE_CALL();
- mNativeWindow = window;
+ mNativeSurface = surface;
if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface);
mEglSurface = EGL_NO_SURFACE;
}
- if (window) {
- mEglSurface = mEglManager.createSurface(window);
+ if (surface) {
+ mEglSurface = mEglManager.createSurface(surface);
}
if (mEglSurface != EGL_NO_SURFACE) {
@@ -131,8 +131,8 @@
mSwapBehavior = swapBehavior;
}
-void CanvasContext::initialize(ANativeWindow* window) {
- setSurface(window);
+void CanvasContext::initialize(Surface* surface) {
+ setSurface(surface);
#if !HWUI_NEW_OPS
if (mCanvas) return;
mCanvas = new OpenGLRenderer(mRenderThread.renderState());
@@ -140,11 +140,11 @@
#endif
}
-void CanvasContext::updateSurface(ANativeWindow* window) {
- setSurface(window);
+void CanvasContext::updateSurface(Surface* surface) {
+ setSurface(surface);
}
-bool CanvasContext::pauseSurface(ANativeWindow* window) {
+bool CanvasContext::pauseSurface(Surface* surface) {
return mRenderThread.removeFrameCallback(this);
}
@@ -208,6 +208,10 @@
info.renderer = mCanvas;
#endif
+ if (CC_LIKELY(mNativeSurface.get())) {
+ info.frameNumber = static_cast<int64_t>(mNativeSurface->getNextFrameNumber());
+ }
+
mAnimationContext->startFrame(info.mode);
for (const sp<RenderNode>& node : mRenderNodes) {
// Only the primary target node will be drawn full - all other nodes would get drawn in
@@ -223,7 +227,7 @@
freePrefetechedLayers();
GL_CHECKPOINT(MODERATE);
- if (CC_UNLIKELY(!mNativeWindow.get())) {
+ if (CC_UNLIKELY(!mNativeSurface.get())) {
mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
info.out.canDrawThisFrame = false;
return;
@@ -246,8 +250,9 @@
} else {
// We're maybe behind? Find out for sure
int runningBehind = 0;
- mNativeWindow->query(mNativeWindow.get(),
- NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind);
+ // TODO: Have this method be on Surface, too, not just ANativeWindow...
+ ANativeWindow* window = mNativeSurface.get();
+ window->query(window, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind);
info.out.canDrawThisFrame = !runningBehind;
}
} else {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 270fb1f..00830e4 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -38,6 +38,7 @@
#include <SkBitmap.h>
#include <SkRect.h>
#include <utils/Functor.h>
+#include <gui/Surface.h>
#include <set>
#include <string>
@@ -74,10 +75,10 @@
// Won't take effect until next EGLSurface creation
void setSwapBehavior(SwapBehavior swapBehavior);
- void initialize(ANativeWindow* window);
- void updateSurface(ANativeWindow* window);
- bool pauseSurface(ANativeWindow* window);
- bool hasSurface() { return mNativeWindow.get(); }
+ void initialize(Surface* surface);
+ void updateSurface(Surface* surface);
+ bool pauseSurface(Surface* surface);
+ bool hasSurface() { return mNativeSurface.get(); }
void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
@@ -171,7 +172,7 @@
// lifecycle tracking
friend class android::uirenderer::RenderState;
- void setSurface(ANativeWindow* window);
+ void setSurface(Surface* window);
void requireSurface();
void freePrefetechedLayers();
@@ -181,7 +182,7 @@
RenderThread& mRenderThread;
EglManager& mEglManager;
- sp<ANativeWindow> mNativeWindow;
+ sp<Surface> mNativeSurface;
EGLSurface mEglSurface = EGL_NO_SURFACE;
bool mBufferPreserved = false;
SwapBehavior mSwapBehavior = kSwap_default;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 1d1b144..7c6cd7e 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -139,38 +139,38 @@
postAndWait(task); // block since name/value pointers owned by caller
}
-CREATE_BRIDGE2(initialize, CanvasContext* context, ANativeWindow* window) {
- args->context->initialize(args->window);
+CREATE_BRIDGE2(initialize, CanvasContext* context, Surface* surface) {
+ args->context->initialize(args->surface);
return nullptr;
}
-void RenderProxy::initialize(const sp<ANativeWindow>& window) {
+void RenderProxy::initialize(const sp<Surface>& surface) {
SETUP_TASK(initialize);
args->context = mContext;
- args->window = window.get();
+ args->surface = surface.get();
post(task);
}
-CREATE_BRIDGE2(updateSurface, CanvasContext* context, ANativeWindow* window) {
- args->context->updateSurface(args->window);
+CREATE_BRIDGE2(updateSurface, CanvasContext* context, Surface* surface) {
+ args->context->updateSurface(args->surface);
return nullptr;
}
-void RenderProxy::updateSurface(const sp<ANativeWindow>& window) {
+void RenderProxy::updateSurface(const sp<Surface>& surface) {
SETUP_TASK(updateSurface);
args->context = mContext;
- args->window = window.get();
+ args->surface = surface.get();
postAndWait(task);
}
-CREATE_BRIDGE2(pauseSurface, CanvasContext* context, ANativeWindow* window) {
- return (void*) args->context->pauseSurface(args->window);
+CREATE_BRIDGE2(pauseSurface, CanvasContext* context, Surface* surface) {
+ return (void*) args->context->pauseSurface(args->surface);
}
-bool RenderProxy::pauseSurface(const sp<ANativeWindow>& window) {
+bool RenderProxy::pauseSurface(const sp<Surface>& surface) {
SETUP_TASK(pauseSurface);
args->context = mContext;
- args->window = window.get();
+ args->surface = surface.get();
return (bool) postAndWait(task);
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 4180d802..178724a 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -67,9 +67,9 @@
ANDROID_API bool loadSystemProperties();
ANDROID_API void setName(const char* name);
- ANDROID_API void initialize(const sp<ANativeWindow>& window);
- ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
- ANDROID_API bool pauseSurface(const sp<ANativeWindow>& window);
+ ANDROID_API void initialize(const sp<Surface>& surface);
+ ANDROID_API void updateSurface(const sp<Surface>& surface);
+ ANDROID_API bool pauseSurface(const sp<Surface>& surface);
ANDROID_API void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
ANDROID_API void setLightCenter(const Vector3& lightCenter);