diff options
| -rw-r--r-- | core/java/android/view/RenderNode.java | 5 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 101 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 14 | ||||
| -rw-r--r-- | core/jni/android_view_RenderNode.cpp | 72 | ||||
| -rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 23 | ||||
| -rw-r--r-- | libs/hwui/DamageAccumulator.h | 2 | ||||
| -rw-r--r-- | libs/hwui/RenderNode.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/RenderNode.h | 15 | ||||
| -rw-r--r-- | libs/hwui/TreeInfo.h | 6 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 29 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 13 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 24 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 6 | ||||
| -rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 9 | ||||
| -rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java | 125 |
15 files changed, 364 insertions, 84 deletions
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index 88bffb5827aa..3122c0be30fe 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -135,6 +135,9 @@ public class RenderNode { private RenderNode(String name, View owningView) { mNativeRenderNode = nCreate(name); mOwningView = owningView; + if (mOwningView instanceof SurfaceView) { + nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView); + } } /** @@ -854,6 +857,8 @@ public class RenderNode { private static native void nOutput(long renderNode); private static native int nGetDebugSize(long renderNode); + private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback); + /////////////////////////////////////////////////////////////////////////// // Animations /////////////////////////////////////////////////////////////////////////// diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 5b48e2893fc7..a2960515da08 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -135,7 +135,7 @@ public class SurfaceView extends View { } }; - final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener + private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { @@ -143,6 +143,17 @@ public class SurfaceView extends View { } }; + private final ViewTreeObserver.OnPreDrawListener mDrawListener = + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + // reposition ourselves where the surface is + mHaveFrame = getWidth() > 0 && getHeight() > 0; + updateWindow(false, false); + return true; + } + }; + boolean mRequestedVisible = false; boolean mWindowVisibility = false; boolean mViewVisibility = false; @@ -168,17 +179,9 @@ public class SurfaceView extends View { boolean mUpdateWindowNeeded; boolean mReportDrawNeeded; private Translator mTranslator; + private int mWindowInsetLeft; + private int mWindowInsetTop; - private final ViewTreeObserver.OnPreDrawListener mDrawListener = - new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - // reposition ourselves where the surface is - mHaveFrame = getWidth() > 0 && getHeight() > 0; - updateWindow(false, false); - return true; - } - }; private boolean mGlobalListenersAdded; public SurfaceView(Context context) { @@ -443,17 +446,17 @@ public class SurfaceView extends View { int myHeight = mRequestedHeight; if (myHeight <= 0) myHeight = getHeight(); - getLocationInWindow(mLocation); final boolean creating = mWindow == null; final boolean formatChanged = mFormat != mRequestedFormat; final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; final boolean visibleChanged = mVisible != mRequestedVisible; final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height; - final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; if (force || creating || formatChanged || sizeChanged || visibleChanged || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) { + getLocationInWindow(mLocation); + if (DEBUG) Log.i(TAG, "Changes: creating=" + creating + " format=" + formatChanged + " size=" + sizeChanged + " visible=" + visibleChanged @@ -643,24 +646,66 @@ public class SurfaceView extends View { TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + " w=" + mLayout.width + " h=" + mLayout.height + ", frame=" + mSurfaceFrame); - } else if (positionChanged || layoutSizeChanged) { // Only the position has changed - mWindowSpaceLeft = mLocation[0]; - mWindowSpaceTop = mLocation[1]; - // For our size changed check, we keep mLayout.width and mLayout.height - // in view local space. - mLocation[0] = mLayout.width = getWidth(); - mLocation[1] = mLayout.height = getHeight(); + } else if (!isHardwareAccelerated()) { + getLocationInWindow(mLocation); + final boolean positionChanged = mWindowSpaceLeft != mLocation[0] + || mWindowSpaceTop != mLocation[1]; + if (positionChanged || layoutSizeChanged) { // Only the position has changed + mWindowSpaceLeft = mLocation[0]; + mWindowSpaceTop = mLocation[1]; + // For our size changed check, we keep mLayout.width and mLayout.height + // in view local space. + mLocation[0] = mLayout.width = getWidth(); + mLocation[1] = mLayout.height = getHeight(); - transformFromViewToWindowSpace(mLocation); + transformFromViewToWindowSpace(mLocation); - try { - mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop, - mLocation[0], mLocation[1], - viewRoot != null ? viewRoot.getNextFrameNumber() : -1, - mWinFrame); - } catch (RemoteException ex) { - Log.e(TAG, "Exception from relayout", ex); + try { + Log.d(TAG, String.format("updateWindowPosition UI, " + + "postion = [%d, %d, %d, %d]", mWindowSpaceLeft, mWindowSpaceTop, + mLocation[0], mLocation[1])); + mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop, + mLocation[0], mLocation[1], -1, mWinFrame); + } catch (RemoteException ex) { + Log.e(TAG, "Exception from relayout", ex); + } + } + } + } + + private Rect mRTLastReportedPosition = new Rect(); + + /** + * Called by native on RenderThread to update the window position + * @hide + */ + public final void updateWindowPositionRT(long frameNumber, + int left, int top, int right, int bottom) { + IWindowSession session = mSession; + MyWindow window = mWindow; + if (session == null || window == null) { + // Guess we got detached, that sucks + return; + } + if (mRTLastReportedPosition.left == left + && mRTLastReportedPosition.top == top + && mRTLastReportedPosition.right == right + && mRTLastReportedPosition.bottom == bottom) { + return; + } + try { + if (DEBUG) { + Log.d(TAG, String.format("updateWindowPosition RT, frameNr = %d, " + + "postion = [%d, %d, %d, %d]", frameNumber, left, top, + right, bottom)); } + // Just using mRTLastReportedPosition as a dummy rect here + session.repositionChild(window, left, top, right, bottom, frameNumber, + mRTLastReportedPosition); + // Now overwrite mRTLastReportedPosition with our values + mRTLastReportedPosition.set(left, top, right, bottom); + } catch (RemoteException ex) { + Log.e(TAG, "Exception from repositionChild", ex); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 98e32891e033..97e014329331 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6815,20 +6815,6 @@ public final class ViewRootImpl implements ViewParent, } } - long getNextFrameNumber() { - long frameNumber = -1; - if (mSurfaceHolder != null) { - mSurfaceHolder.mSurfaceLock.lock(); - } - if (mSurface.isValid()) { - frameNumber = mSurface.getNextFrameNumber(); - } - if (mSurfaceHolder != null) { - mSurfaceHolder.mSurfaceLock.unlock(); - } - return frameNumber; - } - class TakenSurfaceHolder extends BaseSurfaceHolder { @Override public boolean onAllowLockCanvas() { diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index b1d4e2646ba4..a9003c1888d2 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -15,6 +15,7 @@ */ #define LOG_TAG "OpenGLRenderer" +#define ATRACE_TAG ATRACE_TAG_VIEW #include <EGL/egl.h> @@ -24,7 +25,10 @@ #include <android_runtime/AndroidRuntime.h> #include <Animator.h> +#include <DamageAccumulator.h> +#include <Matrix.h> #include <RenderNode.h> +#include <TreeInfo.h> #include <Paint.h> #include "core_jni_helpers.h" @@ -462,6 +466,69 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz, } // ---------------------------------------------------------------------------- +// SurfaceView position callback +// ---------------------------------------------------------------------------- + +jmethodID gSurfaceViewPositionUpdateMethod; + +static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, + jlong renderNodePtr, jobject surfaceview) { + class SurfaceViewPositionUpdater : public RenderNode::PositionListener { + public: + SurfaceViewPositionUpdater(JNIEnv* env, jobject surfaceview) { + env->GetJavaVM(&mVm); + mWeakRef = env->NewWeakGlobalRef(surfaceview); + } + + virtual ~SurfaceViewPositionUpdater() { + jnienv()->DeleteWeakGlobalRef(mWeakRef); + mWeakRef = nullptr; + } + + virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override { + if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return; + ATRACE_NAME("Update SurfaceView position"); + + JNIEnv* env = jnienv(); + jobject localref = env->NewLocalRef(mWeakRef); + if (CC_UNLIKELY(!localref)) { + jnienv()->DeleteWeakGlobalRef(mWeakRef); + mWeakRef = nullptr; + return; + } + Matrix4 transform; + info.damageAccumulator->computeCurrentTransform(&transform); + const RenderProperties& props = node.properties(); + uirenderer::Rect bounds(props.getWidth(), props.getHeight()); + transform.mapRect(bounds); + bounds.left -= info.windowInsetLeft; + bounds.right -= info.windowInsetLeft; + bounds.top -= info.windowInsetTop; + bounds.bottom -= info.windowInsetTop; + env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod, + (jlong) info.frameNumber, (jint) bounds.left, (jint) bounds.top, + (jint) bounds.right, (jint) bounds.bottom); + env->DeleteLocalRef(localref); + } + + private: + JNIEnv* jnienv() { + JNIEnv* env; + if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { + LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm); + } + return env; + } + + JavaVM* mVm; + jobject mWeakRef; + }; + + RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); + renderNode->setPositionListener(new SurfaceViewPositionUpdater(env, surfaceview)); +} + +// ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- @@ -539,9 +606,14 @@ static const JNINativeMethod gMethods[] = { { "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator }, { "nEndAllAnimators", "(J)V", (void*) android_view_RenderNode_endAllAnimators }, + + { "nRequestPositionUpdates", "(JLandroid/view/SurfaceView;)V", (void*) android_view_RenderNode_requestPositionUpdates }, }; int register_android_view_RenderNode(JNIEnv* env) { + jclass clazz = FindClassOrDie(env, "android/view/SurfaceView"); + gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz, + "updateWindowPositionRT", "(JIIII)V"); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index edced5616b66..506395b312c5 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -133,7 +133,14 @@ public: virtual void prepareTree(TreeInfo& info) { info.errorHandler = this; + // TODO: This is hacky + info.windowInsetLeft = -stagingProperties().getLeft(); + info.windowInsetTop = -stagingProperties().getTop(); + info.updateWindowPositions = true; RenderNode::prepareTree(info); + info.updateWindowPositions = false; + info.windowInsetLeft = 0; + info.windowInsetTop = 0; info.errorHandler = NULL; } @@ -368,28 +375,28 @@ static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz, static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); - sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface); - proxy->initialize(window); + sp<Surface> surface = android_view_Surface_getSurface(env, jsurface); + proxy->initialize(surface); } static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); - sp<ANativeWindow> window; + sp<Surface> surface; if (jsurface) { - window = android_view_Surface_getNativeWindow(env, jsurface); + surface = android_view_Surface_getSurface(env, jsurface); } - proxy->updateSurface(window); + proxy->updateSurface(surface); } static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); - sp<ANativeWindow> window; + sp<Surface> surface; if (jsurface) { - window = android_view_Surface_getNativeWindow(env, jsurface); + surface = android_view_Surface_getSurface(env, jsurface); } - return proxy->pauseSurface(window); + return proxy->pauseSurface(surface); } static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr, diff --git a/libs/hwui/DamageAccumulator.h b/libs/hwui/DamageAccumulator.h index e44fc20feaa8..250296ecc89f 100644 --- a/libs/hwui/DamageAccumulator.h +++ b/libs/hwui/DamageAccumulator.h @@ -57,7 +57,7 @@ public: // 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 d4588edea207..bade216b3b21 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -381,6 +381,10 @@ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) { 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 8e4a3df271f5..f248de54acba 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -209,6 +209,19 @@ public: 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 @@ private: // 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 be25516c587a..accd3038cb9c 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -86,6 +86,12 @@ public: #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 e7cf3ecd2b72..8207bdb79c86 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -96,18 +96,18 @@ void CanvasContext::destroy() { } } -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 @@ void CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) { 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 @@ void CanvasContext::initialize(ANativeWindow* window) { #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 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, 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 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, 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 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, } 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 270fb1fead83..00830e474a8b 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 @@ public: // 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 @@ private: // lifecycle tracking friend class android::uirenderer::RenderState; - void setSurface(ANativeWindow* window); + void setSurface(Surface* window); void requireSurface(); void freePrefetechedLayers(); @@ -181,7 +182,7 @@ private: 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 1d1b144bd47e..7c6cd7e014ef 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -139,38 +139,38 @@ void RenderProxy::setName(const char* name) { 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 4180d8020179..178724a85d04 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -67,9 +67,9 @@ public: 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); diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index b028ce61f821..de7b9c268c99 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -356,6 +356,15 @@ </activity> <activity + android:name="MovingSurfaceViewActivity" + android:label="SurfaceView/Animated Movement"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.android.test.hwui.TEST" /> + </intent-filter> + </activity> + + <activity android:name="GLTextureViewActivity" android:label="TextureView/OpenGL"> <intent-filter> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java new file mode 100644 index 000000000000..cd15ef156a5c --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.SurfaceHolder; +import android.view.SurfaceHolder.Callback; +import android.view.SurfaceView; +import android.view.View; +import android.view.animation.LinearInterpolator; +import android.widget.FrameLayout; + +public class MovingSurfaceViewActivity extends Activity implements Callback { + static final String TAG = "MovingSurfaceView"; + SurfaceView mSurfaceView; + ObjectAnimator mAnimator; + + class MySurfaceView extends SurfaceView { + boolean mSlowToggled; + + public MySurfaceView(Context context) { + super(context); + setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mSlowToggled = !mSlowToggled; + Log.d(TAG, "SLOW MODE: " + mSlowToggled); + invalidate(); + } + }); + setWillNotDraw(false); + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + if (mSlowToggled) { + try { + Thread.sleep(16); + } catch (InterruptedException e) {} + } + } + + public void setMyTranslationY(float ty) { + setTranslationY(ty); + if (mSlowToggled) { + invalidate(); + } + } + + public float getMyTranslationY() { + return getTranslationY(); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout content = new FrameLayout(this); + + mSurfaceView = new MySurfaceView(this); + mSurfaceView.getHolder().addCallback(this); + + final float density = getResources().getDisplayMetrics().density; + int size = (int) (200 * density); + + content.addView(mSurfaceView, new FrameLayout.LayoutParams( + size, size, Gravity.CENTER)); + mAnimator = ObjectAnimator.ofFloat(mSurfaceView, "myTranslationY", + 0, size); + mAnimator.setRepeatMode(ObjectAnimator.REVERSE); + mAnimator.setRepeatCount(ObjectAnimator.INFINITE); + mAnimator.setDuration(200); + mAnimator.setInterpolator(new LinearInterpolator()); + setContentView(content); + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + Canvas canvas = holder.lockCanvas(); + canvas.drawARGB(0xFF, 0x00, 0xFF, 0x00); + holder.unlockCanvasAndPost(canvas); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + } + + @Override + protected void onResume() { + super.onResume(); + mAnimator.start(); + } + + @Override + protected void onPause() { + mAnimator.pause(); + super.onPause(); + } +} |