Merge "BufferQueue: Add allocateBuffers method"
diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp
index 4b5aba9..3155766 100644
--- a/cmds/flatland/GLHelper.cpp
+++ b/cmds/flatland/GLHelper.cpp
@@ -205,7 +205,7 @@
     sp<IGraphicBufferConsumer> consumer;
     BufferQueue::createBufferQueue(&producer, &consumer, mGraphicBufferAlloc);
     sp<GLConsumer> glc = new GLConsumer(consumer, name,
-            GL_TEXTURE_EXTERNAL_OES, false);
+            GL_TEXTURE_EXTERNAL_OES, false, true);
     glc->setDefaultBufferSize(w, h);
     glc->setDefaultMaxBufferCount(3);
     glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 974c865..ca30f91 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -633,6 +633,11 @@
     bool profiler = (property_get("dalvik.vm.profiler", prop_buf, "0") > 0) && (prop_buf[0] == '1');
 
     static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
+
+    // TODO: Make this memory value configurable with a system property b/15919420
+    static const char* RUNTIME_ARG = "--runtime-arg";
+    static const char* MEMORY_MAX_ARG = "-Xmx512m";
+
     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 32;
 
@@ -676,12 +681,14 @@
 
     ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
 
-    char* argv[7  // program name, mandatory arguments and the final NULL
+    char* argv[9  // program name, mandatory arguments and the final NULL
                + (have_profile_file ? 1 : 0)
                + (have_top_k_profile_threshold ? 1 : 0)
                + (have_dex2oat_flags ? 1 : 0)];
     int i = 0;
     argv[i++] = (char*)DEX2OAT_BIN;
+    argv[i++] = (char*)RUNTIME_ARG;
+    argv[i++] = (char*)MEMORY_MAX_ARG;
     argv[i++] = zip_fd_arg;
     argv[i++] = zip_location_arg;
     argv[i++] = oat_fd_arg;
@@ -1384,10 +1391,11 @@
 
 static int prune_dex_exclusion_predicate(const char *file_name, const int is_dir)
 {
-    // Don't exclude any directories, we want to inspect them
-    // recusively for files.
+    // Exclude all directories. The top level command will be
+    // given a list of ISA specific directories that are assumed
+    // to be flat.
     if (is_dir) {
-      return 0;
+      return 1;
     }
 
 
@@ -1405,6 +1413,26 @@
     return 1;
 }
 
-int prune_dex_cache() {
-  return delete_dir_contents(DALVIK_CACHE_PREFIX, 0, &prune_dex_exclusion_predicate);
+int prune_dex_cache(const char* subdir) {
+    // "." is handled as a special case, and refers to
+    // DALVIK_CACHE_PREFIX (usually /data/dalvik-cache).
+    const bool is_dalvik_cache_root = !strcmp(subdir, ".");
+
+    // Don't allow the path to contain "." or ".." except for the
+    // special case above. This is much stricter than we need to be,
+    // but there's no good reason to support them.
+    if (strchr(subdir, '.' ) != NULL && !is_dalvik_cache_root) {
+        return -1;
+    }
+
+    if (!is_dalvik_cache_root) {
+        char full_path[PKG_PATH_MAX];
+        snprintf(full_path, sizeof(full_path), "%s%s", DALVIK_CACHE_PREFIX, subdir);
+        return delete_dir_contents(full_path, 0, &prune_dex_exclusion_predicate);
+    }
+
+
+    // When subdir == ".", clean the contents of the top level
+    // dalvik-cache directory.
+    return delete_dir_contents(DALVIK_CACHE_PREFIX, 0, &prune_dex_exclusion_predicate);
 }
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 4368a9e..45cc2b2 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -143,7 +143,7 @@
 static int do_prune_dex_cache(char **arg __attribute__((unused)),
                               char reply[REPLY_MAX] __attribute__((unused)))
 {
-    return prune_dex_cache();
+    return prune_dex_cache(arg[0] /* subdirectory name */);
 }
 
 struct cmdinfo {
@@ -172,7 +172,7 @@
     { "rmuser",               1, do_rm_user },
     { "idmap",                3, do_idmap },
     { "restorecondata",       3, do_restorecon_data },
-    { "prunedexcache",        0, do_prune_dex_cache },
+    { "prunedexcache",        1, do_prune_dex_cache },
 };
 
 static int readx(int s, void *_buf, int count)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index c1e6e0f..f193b46 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -220,4 +220,4 @@
 int linklib(const char* target, const char* source, int userId);
 int idmap(const char *target_path, const char *overlay_path, uid_t uid);
 int restorecon_data();
-int prune_dex_cache();
+int prune_dex_cache(const char* subdir);
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index a5fdfb9..1aacee9 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -52,28 +52,17 @@
  * This class was previously called SurfaceTexture.
  */
 class GLConsumer : public ConsumerBase {
-protected:
-    enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES
 public:
+    enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES
     typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
 
-    // GLConsumer constructs a new GLConsumer object. tex indicates the
-    // name of the OpenGL ES texture to which images are to be streamed.
-    // allowSynchronousMode specifies whether or not synchronous mode can be
-    // enabled. texTarget specifies the OpenGL ES texture target to which the
-    // texture will be bound in updateTexImage. useFenceSync specifies whether
-    // fences should be used to synchronize access to buffers if that behavior
-    // is enabled at compile-time. A custom bufferQueue can be specified
-    // if behavior for queue/dequeue/connect etc needs to be customized.
-    // Otherwise a default BufferQueue will be created and used.
-    //
-    // For legacy reasons, the GLConsumer is created in a state where it is
-    // considered attached to an OpenGL ES context for the purposes of the
-    // attachToContext and detachFromContext methods. However, despite being
-    // considered "attached" to a context, the specific OpenGL ES context
-    // doesn't get latched until the first call to updateTexImage. After that
-    // point, all calls to updateTexImage must be made with the same OpenGL ES
-    // context current.
+    // GLConsumer constructs a new GLConsumer object. If the constructor with
+    // the tex parameter is used, tex indicates the name of the OpenGL ES
+    // texture to which images are to be streamed. texTarget specifies the
+    // OpenGL ES texture target to which the texture will be bound in
+    // updateTexImage. useFenceSync specifies whether fences should be used to
+    // synchronize access to buffers if that behavior is enabled at
+    // compile-time.
     //
     // A GLConsumer may be detached from one OpenGL ES context and then
     // attached to a different context using the detachFromContext and
@@ -81,9 +70,24 @@
     // purely to allow a GLConsumer to be transferred from one consumer
     // context to another. If such a transfer is not needed there is no
     // requirement that either of these methods be called.
+    //
+    // If the constructor with the tex parameter is used, the GLConsumer is
+    // created in a state where it is considered attached to an OpenGL ES
+    // context for the purposes of the attachToContext and detachFromContext
+    // methods. However, despite being considered "attached" to a context, the
+    // specific OpenGL ES context doesn't get latched until the first call to
+    // updateTexImage. After that point, all calls to updateTexImage must be
+    // made with the same OpenGL ES context current.
+    //
+    // If the constructor without the tex parameter is used, the GLConsumer is
+    // created in a detached state, and attachToContext must be called before
+    // calls to updateTexImage.
     GLConsumer(const sp<IGraphicBufferConsumer>& bq,
-            uint32_t tex, uint32_t texureTarget = TEXTURE_EXTERNAL,
-            bool useFenceSync = true, bool isControlledByApp = false);
+            uint32_t tex, uint32_t texureTarget, bool useFenceSync,
+            bool isControlledByApp);
+
+    GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texureTarget,
+            bool useFenceSync, bool isControlledByApp);
 
     // updateTexImage acquires the most recently queued buffer, and sets the
     // image contents of the target texture to it.
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 3215b2f..924fc0d 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -143,6 +143,33 @@
     mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
 }
 
+GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
+        bool useFenceSync, bool isControlledByApp) :
+    ConsumerBase(bq, isControlledByApp),
+    mCurrentTransform(0),
+    mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+    mCurrentFence(Fence::NO_FENCE),
+    mCurrentTimestamp(0),
+    mCurrentFrameNumber(0),
+    mDefaultWidth(1),
+    mDefaultHeight(1),
+    mFilteringEnabled(true),
+    mTexName(-1),
+    mUseFenceSync(useFenceSync),
+    mTexTarget(texTarget),
+    mEglDisplay(EGL_NO_DISPLAY),
+    mEglContext(EGL_NO_CONTEXT),
+    mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
+    mAttached(false)
+{
+    ST_LOGV("GLConsumer");
+
+    memcpy(mCurrentTransformMatrix, mtxIdentity,
+            sizeof(mCurrentTransformMatrix));
+
+    mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
+}
+
 status_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) {
     Mutex::Autolock lock(mMutex);
     return mConsumer->setDefaultMaxBufferCount(bufferCount);
diff --git a/libs/gui/tests/MultiTextureConsumer_test.cpp b/libs/gui/tests/MultiTextureConsumer_test.cpp
index 1eb6ef6..3a25ac5 100644
--- a/libs/gui/tests/MultiTextureConsumer_test.cpp
+++ b/libs/gui/tests/MultiTextureConsumer_test.cpp
@@ -37,7 +37,8 @@
         sp<IGraphicBufferProducer> producer;
         sp<IGraphicBufferConsumer> consumer;
         BufferQueue::createBufferQueue(&producer, &consumer);
-        mGlConsumer = new GLConsumer(consumer, TEX_ID);
+        mGlConsumer = new GLConsumer(consumer, TEX_ID,
+                GLConsumer::TEXTURE_EXTERNAL, true, false);
         mSurface = new Surface(producer);
         mANW = mSurface.get();
 
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 7f9fcc4..8cdf3bc 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -46,7 +46,8 @@
         sp<IGraphicBufferProducer> producer;
         sp<IGraphicBufferConsumer> consumer;
         BufferQueue::createBufferQueue(&producer, &consumer);
-        mST = new GLConsumer(consumer, 123);
+        mST = new GLConsumer(consumer, 123, GLConsumer::TEXTURE_EXTERNAL, true,
+                false);
         mSTC = new Surface(producer);
         mANW = mSTC;
 
@@ -716,7 +717,8 @@
             sp<IGraphicBufferProducer> producer;
             sp<IGraphicBufferConsumer> consumer;
             BufferQueue::createBufferQueue(&producer, &consumer);
-            sp<GLConsumer> st(new GLConsumer(consumer, i));
+            sp<GLConsumer> st(new GLConsumer(consumer, i,
+                    GLConsumer::TEXTURE_EXTERNAL, true, false));
             sp<Surface> stc(new Surface(producer));
             mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
                     static_cast<ANativeWindow*>(stc.get()), NULL);
diff --git a/libs/gui/tests/SurfaceTextureGL.h b/libs/gui/tests/SurfaceTextureGL.h
index 3bff192..53eb68c 100644
--- a/libs/gui/tests/SurfaceTextureGL.h
+++ b/libs/gui/tests/SurfaceTextureGL.h
@@ -39,7 +39,8 @@
         GLTest::SetUp();
         sp<IGraphicBufferProducer> producer;
         BufferQueue::createBufferQueue(&producer, &mConsumer);
-        mST = new GLConsumer(mConsumer, TEX_ID);
+        mST = new GLConsumer(mConsumer, TEX_ID, GLConsumer::TEXTURE_EXTERNAL,
+                true, false);
         mSTC = new Surface(producer);
         mANW = mSTC;
         mTextureRenderer = new TextureRenderer(TEX_ID, mST);
diff --git a/services/inputflinger/Android.mk b/services/inputflinger/Android.mk
index 574c14e..2edc07d 100644
--- a/services/inputflinger/Android.mk
+++ b/services/inputflinger/Android.mk
@@ -27,6 +27,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libbinder \
+    libcrypto \
     libcutils \
     libinput \
     liblog \
@@ -38,6 +39,9 @@
 # TODO: Move inputflinger to its own process and mark it hidden
 #LOCAL_CFLAGS += -fvisibility=hidden
 
+LOCAL_C_INCLUDES := \
+    external/openssl/include \
+
 LOCAL_CFLAGS += -Wno-unused-parameter
 
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index f274631..dfe5d3d 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -28,7 +28,6 @@
 #include <sys/limits.h>
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
-#include <sys/sha1.h>
 #include <sys/utsname.h>
 #include <unistd.h>
 
@@ -41,6 +40,7 @@
 #include <hardware_legacy/power.h>
 
 #include <cutils/properties.h>
+#include <openssl/sha.h>
 #include <utils/Log.h>
 #include <utils/Timers.h>
 #include <utils/threads.h>
@@ -80,14 +80,14 @@
 }
 
 static String8 sha1(const String8& in) {
-    SHA1_CTX ctx;
-    SHA1Init(&ctx);
-    SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
-    u_char digest[SHA1_DIGEST_LENGTH];
-    SHA1Final(digest, &ctx);
+    SHA_CTX ctx;
+    SHA1_Init(&ctx);
+    SHA1_Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
+    u_char digest[SHA_DIGEST_LENGTH];
+    SHA1_Final(digest, &ctx);
 
     String8 out;
-    for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+    for (size_t i = 0; i < SHA_DIGEST_LENGTH; i++) {
         out.appendFormat("%02x", digest[i]);
     }
     return out;
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 56c539f..0e15506 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -93,7 +93,8 @@
 	libGLESv2 \
 	libbinder \
 	libui \
-	libgui
+	libgui \
+	libpowermanager
 
 LOCAL_MODULE:= libsurfaceflinger
 
diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
index e41fbbc..bd50b4a 100644
--- a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
@@ -20,38 +20,30 @@
 #include <cutils/log.h>
 #include <utils/Errors.h>
 
+#include <binder/IServiceManager.h>
+#include <powermanager/IPowerManager.h>
+#include <powermanager/PowerManager.h>
+
 #include "PowerHAL.h"
 
 namespace android {
 // ---------------------------------------------------------------------------
 
-PowerHAL::PowerHAL() : mPowerModule(0), mVSyncHintEnabled(false) {
-    int err = hw_get_module(POWER_HARDWARE_MODULE_ID,
-            (const hw_module_t **)&mPowerModule);
-    ALOGW_IF(err, "%s module not found", POWER_HARDWARE_MODULE_ID);
-}
-
-PowerHAL::~PowerHAL() {
-}
-
-status_t PowerHAL::initCheck() const {
-    return mPowerModule ? NO_ERROR : NO_INIT;
-}
-
 status_t PowerHAL::vsyncHint(bool enabled) {
-    if (!mPowerModule) {
-        return NO_INIT;
-    }
-    if (mPowerModule->common.module_api_version >= POWER_MODULE_API_VERSION_0_2) {
-        if (mPowerModule->powerHint) {
-            if (mVSyncHintEnabled != bool(enabled)) {
-                mPowerModule->powerHint(mPowerModule,
-                        POWER_HINT_VSYNC, (void*)enabled);
-                mVSyncHintEnabled = bool(enabled);
-            }
+    Mutex::Autolock _l(mlock);
+    if (mPowerManager == NULL) {
+        const String16 serviceName("power");
+        sp<IBinder> bs = defaultServiceManager()->checkService(serviceName);
+        if (bs == NULL) {
+            return NAME_NOT_FOUND;
         }
+        mPowerManager = interface_cast<IPowerManager>(bs);
     }
-    return NO_ERROR;
+    status_t status = mPowerManager->powerHint(POWER_HINT_VSYNC, enabled ? 1 : 0);
+    if(status == DEAD_OBJECT) {
+        mPowerManager = NULL;
+    }
+    return status;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.h b/services/surfaceflinger/DisplayHardware/PowerHAL.h
index ef67b8f..e5f82a9 100644
--- a/services/surfaceflinger/DisplayHardware/PowerHAL.h
+++ b/services/surfaceflinger/DisplayHardware/PowerHAL.h
@@ -19,7 +19,9 @@
 
 #include <stdint.h>
 #include <sys/types.h>
+#include <utils/Mutex.h>
 
+#include <powermanager/IPowerManager.h>
 #include <hardware/power.h>
 
 namespace android {
@@ -28,15 +30,11 @@
 class PowerHAL
 {
 public:
-    PowerHAL();
-    ~PowerHAL();
-
-    status_t initCheck() const;
     status_t vsyncHint(bool enabled);
 
 private:
-    power_module_t*   mPowerModule;
-    bool mVSyncHintEnabled;
+    sp<IPowerManager> mPowerManager;
+    Mutex mlock;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index d868f32..9b6360e 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -35,12 +35,21 @@
 // ---------------------------------------------------------------------------
 namespace android {
 // ---------------------------------------------------------------------------
+// time to wait between VSYNC requests before sending a VSYNC OFF power hint: 40msec.
+const long vsyncHintOffDelay = 40000000;
+
+static void vsyncOffCallback(union sigval val) {
+    EventThread *ev = (EventThread *)val.sival_ptr;
+    ev->sendVsyncHintOff();
+    return;
+}
 
 EventThread::EventThread(const sp<VSyncSource>& src)
     : mVSyncSource(src),
       mUseSoftwareVSync(false),
       mVsyncEnabled(false),
-      mDebugVsyncEnabled(false) {
+      mDebugVsyncEnabled(false),
+      mVsyncHintSent(false) {
 
     for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
         mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
@@ -48,6 +57,31 @@
         mVSyncEvent[i].header.timestamp = 0;
         mVSyncEvent[i].vsync.count =  0;
     }
+    struct sigevent se;
+    se.sigev_notify = SIGEV_THREAD;
+    se.sigev_value.sival_ptr = this;
+    se.sigev_notify_function = vsyncOffCallback;
+    se.sigev_notify_attributes = NULL;
+    timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
+}
+
+void EventThread::sendVsyncHintOff() {
+    Mutex::Autolock _l(mLock);
+    mPowerHAL.vsyncHint(false);
+    mVsyncHintSent = false;
+}
+
+void EventThread::sendVsyncHintOnLocked() {
+    struct itimerspec ts;
+    if(!mVsyncHintSent) {
+        mPowerHAL.vsyncHint(true);
+        mVsyncHintSent = true;
+    }
+    ts.it_value.tv_sec = 0;
+    ts.it_value.tv_nsec = vsyncHintOffDelay;
+    ts.it_interval.tv_sec = 0;
+    ts.it_interval.tv_nsec = 0;
+    timer_settime(mTimerId, 0, &ts, NULL);
 }
 
 void EventThread::onFirstRef() {
@@ -307,17 +341,16 @@
             mVsyncEnabled = true;
             mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
             mVSyncSource->setVSyncEnabled(true);
-            mPowerHAL.vsyncHint(true);
         }
     }
     mDebugVsyncEnabled = true;
+    sendVsyncHintOnLocked();
 }
 
 void EventThread::disableVSyncLocked() {
     if (mVsyncEnabled) {
         mVsyncEnabled = false;
         mVSyncSource->setVSyncEnabled(false);
-        mPowerHAL.vsyncHint(false);
         mDebugVsyncEnabled = false;
     }
 }
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index f6ab4a7..d1c4fcd 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -97,6 +97,7 @@
             DisplayEventReceiver::Event* event);
 
     void dump(String8& result) const;
+    void sendVsyncHintOff();
 
 private:
     virtual bool        threadLoop();
@@ -107,6 +108,7 @@
     void removeDisplayEventConnection(const wp<Connection>& connection);
     void enableVSyncLocked();
     void disableVSyncLocked();
+    void sendVsyncHintOnLocked();
 
     // constants
     sp<VSyncSource> mVSyncSource;
@@ -124,6 +126,9 @@
 
     // for debugging
     bool mDebugVsyncEnabled;
+
+    bool mVsyncHintSent;
+    timer_t mTimerId;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4ecdc8b..4238ef8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2873,14 +2873,14 @@
     if (sourceCrop.left < 0) {
         ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
     }
-    if (sourceCrop.right >= hw_w) {
-        ALOGE("Invalid crop rect: r = %d (>= %d)", sourceCrop.right, hw_w);
+    if (sourceCrop.right > hw_w) {
+        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
     }
     if (sourceCrop.top < 0) {
         ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
     }
-    if (sourceCrop.bottom >= hw_h) {
-        ALOGE("Invalid crop rect: b = %d (>= %d)", sourceCrop.bottom, hw_h);
+    if (sourceCrop.bottom > hw_h) {
+        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
     }
 
     // make sure to clear all GL error flags
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index ed307c2..5633980 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -34,7 +34,7 @@
 
     SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
             uint32_t tex)
-        : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false),
+        : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
           mTransformToDisplayInverse(false)
     {}