OSDN Git Service

Merge "Use a named constant rather than a magic number." into jb-mr1-dev
authorElliott Hughes <enh@google.com>
Mon, 17 Sep 2012 19:11:24 +0000 (12:11 -0700)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Mon, 17 Sep 2012 19:11:25 +0000 (12:11 -0700)
cmds/dumpstate/dumpstate.c
include/gui/BufferQueue.h
libs/gui/BufferQueue.cpp
libs/gui/tests/SurfaceTexture_test.cpp
libs/utils/SystemClock.cpp
services/surfaceflinger/Layer.cpp
services/surfaceflinger/Layer.h
services/surfaceflinger/LayerBase.h
services/surfaceflinger/SurfaceFlinger.cpp

index 4bb05c4..56ba3c8 100644 (file)
@@ -294,7 +294,7 @@ static void dumpstate() {
 }
 
 static void usage() {
-    fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s]\n"
+    fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n"
             "  -o: write to file (instead of stdout)\n"
             "  -d: append date to filename (requires -o)\n"
             "  -z: gzip output (requires -o)\n"
@@ -302,12 +302,14 @@ static void usage() {
             "  -s: write output to control socket (for init)\n"
             "  -b: play sound file instead of vibrate, at beginning of job\n"
             "  -e: play sound file instead of vibrate, at end of job\n"
+            "  -q: disable vibrate\n"
                );
 }
 
 int main(int argc, char *argv[]) {
     int do_add_date = 0;
     int do_compress = 0;
+    int do_vibrate = 1;
     char* use_outfile = 0;
     char* begin_sound = 0;
     char* end_sound = 0;
@@ -338,7 +340,7 @@ int main(int argc, char *argv[]) {
     dump_traces_path = dump_traces();
 
     int c;
-    while ((c = getopt(argc, argv, "b:de:ho:svzp")) != -1) {
+    while ((c = getopt(argc, argv, "b:de:ho:svqzp")) != -1) {
         switch (c) {
             case 'b': begin_sound = optarg;  break;
             case 'd': do_add_date = 1;       break;
@@ -346,6 +348,7 @@ int main(int argc, char *argv[]) {
             case 'o': use_outfile = optarg;  break;
             case 's': use_socket = 1;        break;
             case 'v': break;  // compatibility no-op
+            case 'q': do_vibrate = 0;        break;
             case 'z': do_compress = 6;       break;
             case 'p': do_fb = 1;             break;
             case '?': printf("\n");
@@ -355,9 +358,12 @@ int main(int argc, char *argv[]) {
         }
     }
 
-    /* open the vibrator before dropping root */
-    FILE *vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
-    if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
+    FILE *vibrator = 0;
+    if (do_vibrate) {
+        /* open the vibrator before dropping root */
+        vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
+        if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
+    }
 
     /* read /proc/cmdline before dropping root */
     FILE *cmdline = fopen("/proc/cmdline", "r");
index 3481c6f..9e265ba 100644 (file)
@@ -402,9 +402,11 @@ private:
         Rect mCrop;
 
         // mTransform is the current transform flags for this buffer slot.
+        // (example: NATIVE_WINDOW_TRANSFORM_ROT_90)
         uint32_t mTransform;
 
         // mScalingMode is the current scaling mode for this buffer slot.
+        // (example: NATIVE_WINDOW_SCALING_MODE_FREEZE)
         uint32_t mScalingMode;
 
         // mTimestamp is the current timestamp for this buffer slot. This gets
index 2eee6f5..8594b84 100644 (file)
@@ -150,6 +150,7 @@ status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
 }
 
 status_t BufferQueue::setTransformHint(uint32_t hint) {
+    ST_LOGV("setTransformHint: %02x", hint);
     Mutex::Autolock lock(mMutex);
     mTransformHint = hint;
     return OK;
@@ -737,9 +738,10 @@ void BufferQueue::dump(String8& result, const char* prefix,
 
     snprintf(buffer, SIZE,
             "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
-            "default-format=%d, FIFO(%d)={%s}\n",
+            "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
             prefix, maxBufferCount, mSynchronousMode, mDefaultWidth,
-            mDefaultHeight, mDefaultBufferFormat, fifoSize, fifo.string());
+            mDefaultHeight, mDefaultBufferFormat, mTransformHint,
+            fifoSize, fifo.string());
     result.append(buffer);
 
 
index 212c6a7..d9b40cf 100644 (file)
@@ -1414,6 +1414,59 @@ protected:
     EGLContext mProducerEglContext;
 };
 
+TEST_F(SurfaceTextureGLToGLTest, TransformHintGetsRespected) {
+    const uint32_t texWidth = 32;
+    const uint32_t texHeight = 64;
+
+    mST->setDefaultBufferSize(texWidth, texHeight);
+    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
+
+    // This test requires 3 buffers to avoid deadlock because we're
+    // both producer and consumer, and only using one thread.
+    mST->setDefaultMaxBufferCount(3);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Start a buffer with our chosen size and transform hint moving
+    // through the system.
+    glClear(GL_COLOR_BUFFER_BIT);  // give the driver something to do
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();  // consume it
+    // Swap again.
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();
+
+    // The current buffer should either show the effects of the transform
+    // hint (in the form of an inverse transform), or show that the
+    // transform hint has been ignored.
+    sp<GraphicBuffer> buf = mST->getCurrentBuffer();
+    if (mST->getCurrentTransform() == NATIVE_WINDOW_TRANSFORM_ROT_270) {
+        ASSERT_EQ(texWidth, buf->getHeight());
+        ASSERT_EQ(texHeight, buf->getWidth());
+    } else {
+        ASSERT_EQ(texWidth, buf->getWidth());
+        ASSERT_EQ(texHeight, buf->getHeight());
+    }
+
+    // Reset the transform hint and confirm that it takes.
+    mST->setTransformHint(0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();
+
+    buf = mST->getCurrentBuffer();
+    ASSERT_EQ((uint32_t) 0, mST->getCurrentTransform());
+    ASSERT_EQ(texWidth, buf->getWidth());
+    ASSERT_EQ(texHeight, buf->getHeight());
+}
+
 TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
     const int texWidth = 64;
     const int texHeight = 64;
index 53e0626..fe4ae91 100644 (file)
@@ -109,6 +109,43 @@ int64_t elapsedRealtime()
        return nanoseconds_to_milliseconds(elapsedRealtimeNano());
 }
 
+#define METHOD_CLOCK_GETTIME    0
+#define METHOD_IOCTL            1
+#define METHOD_SYSTEMTIME       2
+
+static const char *gettime_method_names[] = {
+    "clock_gettime",
+    "ioctl",
+    "systemTime",
+};
+
+static inline void checkTimeStamps(int64_t timestamp,
+                                   int64_t volatile *prevTimestampPtr,
+                                   int volatile *prevMethodPtr,
+                                   int curMethod)
+{
+    /*
+     * Disable the check for SDK since the prebuilt toolchain doesn't contain
+     * gettid, and int64_t is different on the ARM platform
+     * (ie long vs long long).
+     */
+#ifdef ARCH_ARM
+    int64_t prevTimestamp = *prevTimestampPtr;
+    int prevMethod = *prevMethodPtr;
+
+    if (timestamp < prevTimestamp) {
+        ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d",
+              prevTimestamp, gettime_method_names[prevMethod],
+              timestamp, gettime_method_names[curMethod],
+              gettid());
+    }
+    // NOTE - not atomic and may generate spurious warnings if the 64-bit
+    // write is interrupted or not observed as a whole.
+    *prevTimestampPtr = timestamp;
+    *prevMethodPtr = curMethod;
+#endif
+}
+
 /*
  * native public static long elapsedRealtimeNano();
  */
@@ -117,8 +154,15 @@ int64_t elapsedRealtimeNano()
 #ifdef HAVE_ANDROID_OS
     struct timespec ts;
     int result = clock_gettime(CLOCK_BOOTTIME, &ts);
+    int64_t timestamp;
+    static volatile int64_t prevTimestamp;
+    static volatile int prevMethod;
+
     if (result == 0) {
-        return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
+                        METHOD_CLOCK_GETTIME);
+        return timestamp;
     }
 
     // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm
@@ -129,18 +173,24 @@ int64_t elapsedRealtimeNano()
         if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
             close(fd);
         }
-        result = ioctl(s_fd,
-                ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
     }
 
+    result = ioctl(s_fd,
+            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
+
     if (result == 0) {
-        return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);
+        return timestamp;
     }
 
     // XXX: there was an error, probably because the driver didn't
     // exist ... this should return
     // a real error, like an exception!
-    return systemTime(SYSTEM_TIME_MONOTONIC);
+    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+    checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
+                    METHOD_SYSTEMTIME);
+    return timestamp;
 #else
     return systemTime(SYSTEM_TIME_MONOTONIC);
 #endif
index 75eff9f..6785ba8 100644 (file)
@@ -109,6 +109,8 @@ void Layer::onFirstRef()
 #else
     mSurfaceTexture->setDefaultMaxBufferCount(3);
 #endif
+
+    updateTransformHint();
 }
 
 Layer::~Layer()
@@ -429,12 +431,12 @@ uint32_t Layer::doTransaction(uint32_t flags)
     if (sizeChanged) {
         // the size changed, we need to ask our client to request a new buffer
         ALOGD_IF(DEBUG_RESIZE,
-                "doTransaction: geometry (layer=%p), scalingMode=%d\n"
+                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
                 "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                 "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
                 "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                 "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
-                this, mCurrentScalingMode,
+                this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
                 temp.active.w, temp.active.h,
                 temp.active.crop.left,
                 temp.active.crop.top,
@@ -597,10 +599,10 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
                     }
 
                     ALOGD_IF(DEBUG_RESIZE,
-                            "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n"
+                            "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
                             "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
                             "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
-                            this, bufWidth, bufHeight, item.mTransform, item.mScalingMode,
+                            bufWidth, bufHeight, item.mTransform, item.mScalingMode,
                             front.active.w, front.active.h,
                             front.active.crop.left,
                             front.active.crop.top,
@@ -631,10 +633,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
 
         Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
 
-        // XXX: not sure if setTransformHint belongs here
-        // it should only be needed when the main screen orientation changes
-        mSurfaceTexture->setTransformHint(getTransformHint());
-
         if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
             // something happened!
             recomputeVisibleRegions = true;
@@ -711,9 +709,9 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
     snprintf(buffer, SIZE,
             "      "
             "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
-            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
+            " queued-frames=%d, mRefreshPending=%d\n",
             mFormat, w0, h0, s0,f0,
-            getTransformHint(), mQueuedFrames, mRefreshPending);
+            mQueuedFrames, mRefreshPending);
 
     result.append(buffer);
 
@@ -759,7 +757,7 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
     return usage;
 }
 
-uint32_t Layer::getTransformHint() const {
+void Layer::updateTransformHint() const {
     uint32_t orientation = 0;
     if (!mFlinger->mDebugDisableTransformHint) {
         // The transform hint is used to improve performance on the main
@@ -774,7 +772,7 @@ uint32_t Layer::getTransformHint() const {
             orientation = 0;
         }
     }
-    return orientation;
+    mSurfaceTexture->setTransformHint(orientation);
 }
 
 // ---------------------------------------------------------------------------
index 78fe321..b839f8c 100644 (file)
@@ -89,6 +89,10 @@ public:
     // only for debugging
     inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
 
+    // Updates the transform hint in our SurfaceTexture to match
+    // the current orientation of the default display device.
+    virtual void updateTransformHint() const;
+
 protected:
     virtual void onFirstRef();
     virtual void dump(String8& result, char* scratch, size_t size) const;
@@ -100,7 +104,6 @@ private:
     void onFrameQueued();
     virtual sp<ISurface> createSurface();
     uint32_t getEffectiveUsage(uint32_t usage) const;
-    uint32_t getTransformHint() const;
     bool isCropped() const;
     Rect computeBufferCrop() const;
     static bool getOpacityForFormat(uint32_t format);
index 4651517..7326f53 100644 (file)
@@ -229,6 +229,12 @@ public:
      */
     virtual void onPostComposition() { }
 
+    /**
+     * Updates the SurfaceTexture's transform hint, for layers that have
+     * a SurfaceTexture.
+     */
+    virtual void updateTransformHint() const { }
+
     /** always call base class first */
     virtual void dump(String8& result, char* scratch, size_t size) const;
     virtual void shortDump(String8& result, char* scratch, size_t size) const;
index da15248..f1d790d 100644 (file)
@@ -988,6 +988,18 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                             disp->setProjection(state.orientation,
                                     state.viewport, state.frame);
                         }
+
+                        // Walk through all the layers in currentLayers,
+                        // and update their transform hint.
+                        //
+                        // TODO: we could be much more clever about which
+                        // layers we touch and how often we do these updates
+                        // (e.g. only touch the layers associated with this
+                        // display, and only on a rotation).
+                        for (size_t i = 0; i < count; i++) {
+                            const sp<LayerBase>& layerBase = currentLayers[i];
+                            layerBase->updateTransformHint();
+                        }
                     }
                 }
             }