am f56ae199: Merge "Update GLES codegen to be in sync with frameworks/base"

* commit 'f56ae1999948393ba8c207525d6466ee424c4467':
  Update GLES codegen to be in sync with frameworks/base
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 3c79ae9..220af47 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -43,6 +43,8 @@
 
 static char screenshot_path[PATH_MAX] = "";
 
+#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
+
 /* dumps the current system state to stdout */
 static void dumpstate() {
     time_t now = time(NULL);
@@ -161,8 +163,14 @@
     dump_file("NETWORK ROUTES", "/proc/net/route");
     dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
 
-    /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
-    dump_file("LAST KMSG", "/proc/last_kmsg");
+    if (!stat(PSTORE_LAST_KMSG, &st)) {
+        /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
+        dump_file("LAST KMSG", PSTORE_LAST_KMSG);
+    } else {
+        /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
+        dump_file("LAST KMSG", "/proc/last_kmsg");
+    }
+
     dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
     dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
 
@@ -321,7 +329,7 @@
             "  -e: play sound file instead of vibrate, at end of job\n"
             "  -q: disable vibrate\n"
             "  -B: send broadcast when finished (requires -o and -p)\n"
-		);
+                );
 }
 
 static void sigpipe_handler(int n) {
diff --git a/data/etc/android.software.accessibility.xml b/data/etc/android.software.accessibility.xml
new file mode 100644
index 0000000..709b3f0
--- /dev/null
+++ b/data/etc/android.software.accessibility.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<permissions>
+    <feature name="android.software.accessibility" />
+</permissions>
diff --git a/data/etc/android.software.app_widgets.xml b/data/etc/android.software.app_widgets.xml
new file mode 100644
index 0000000..9a51b24
--- /dev/null
+++ b/data/etc/android.software.app_widgets.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<permissions>
+    <feature name="android.software.app_widgets" />
+</permissions>
diff --git a/data/etc/android.software.backup.xml b/data/etc/android.software.backup.xml
new file mode 100644
index 0000000..1ab4603
--- /dev/null
+++ b/data/etc/android.software.backup.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<permissions>
+    <feature name="android.software.backup" />
+</permissions>
diff --git a/data/etc/android.software.device_admin.xml b/data/etc/android.software.device_admin.xml
new file mode 100644
index 0000000..7d14dc6
--- /dev/null
+++ b/data/etc/android.software.device_admin.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<permissions>
+    <feature name="android.software.device_admin" />
+</permissions>
diff --git a/data/etc/android.software.print.xml b/data/etc/android.software.print.xml
new file mode 100644
index 0000000..713a7f7
--- /dev/null
+++ b/data/etc/android.software.print.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<permissions>
+    <feature name="android.software.print" />
+</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 4a9f2dd..3ff8969 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -33,11 +33,18 @@
     <feature name="android.hardware.microphone" />
     <feature name="android.hardware.screen.portrait" />
     <feature name="android.hardware.screen.landscape" />
+
+    <!-- basic system services -->
+    <feature name="android.software.accessibility" />
     <feature name="android.software.app_widgets" />
+    <feature name="android.software.backup" />
     <feature name="android.software.home_screen" />
     <feature name="android.software.input_methods" />
+    <feature name="android.software.print" />
+
     <!-- Feature to specify if the device supports adding device admins. -->
     <feature name="android.software.device_admin" />
+
     <!-- devices with GPS must include android.hardware.location.gps.xml -->
     <!-- devices with an autofocus camera and/or flash must include either
          android.hardware.camera.autofocus.xml or 
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 78b9736..11c5d93 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -34,11 +34,18 @@
     <feature name="android.hardware.microphone" />
     <feature name="android.hardware.screen.portrait" />
     <feature name="android.hardware.screen.landscape" />
+
+    <!-- basic system services -->
+    <feature name="android.software.accessibility" />
     <feature name="android.software.app_widgets" />
+    <feature name="android.software.backup" />
     <feature name="android.software.home_screen" />
     <feature name="android.software.input_methods" />
+    <feature name="android.software.print" />
+
     <!-- Feature to specify if the device supports adding device admins. -->
     <feature name="android.software.device_admin" />
+
     <!-- devices with GPS must include android.hardware.location.gps.xml -->
     <!-- devices with a rear-facing camera must include one of these as appropriate:
          android.hardware.camera.xml or 
diff --git a/data/etc/wearable_core_hardware.xml b/data/etc/wearable_core_hardware.xml
new file mode 100644
index 0000000..c34b25c
--- /dev/null
+++ b/data/etc/wearable_core_hardware.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- These are the hardware and software components that all wearable devices
+     must include. Devices with optional hardware/software must also include
+     extra hardware/software files, per the comments below.
+
+     Wearable devices include watches, glasses, backpacks, and sweaters.
+-->
+<permissions>
+    <feature name="android.hardware.camera" />
+    <feature name="android.hardware.location" />
+    <feature name="android.hardware.location.network" />
+    <feature name="android.hardware.sensor.compass" />
+    <feature name="android.hardware.sensor.accelerometer" />
+    <feature name="android.hardware.bluetooth" />
+    <feature name="android.hardware.touchscreen" />
+    <feature name="android.hardware.microphone" />
+    <feature name="android.hardware.screen.portrait" />
+    <feature name="android.hardware.screen.landscape" />
+
+    <!-- basic system services -->
+    <feature name="android.software.accessibility" />
+    <feature name="android.software.home_screen" />
+    <feature name="android.software.input_methods" />
+
+    <!-- devices with GPS must include android.hardware.location.gps.xml -->
+    <!-- devices with an autofocus camera and/or flash must include either
+         android.hardware.camera.autofocus.xml or
+         android.hardware.camera.autofocus-flash.xml -->
+    <!-- devices with a front facing camera must include
+         android.hardware.camera.front.xml -->
+    <!-- devices with WiFi must also include android.hardware.wifi.xml -->
+    <!-- devices that support multitouch must include the most appropriate one
+         of these files:
+
+         If only partial (non-independent) pointers are supported:
+         android.hardware.touchscreen.multitouch.xml
+
+         If up to 4 independently tracked pointers are supported:
+         include android.hardware.touchscreen.multitouch.distinct.xml
+
+         If 5 or more independently tracked pointers are supported:
+         include android.hardware.touchscreen.multitouch.jazzhand.xml
+
+         ONLY ONE of the above should be included. -->
+    <!-- devices with an ambient light sensor must also include
+         android.hardware.sensor.light.xml -->
+    <!-- devices with a proximity sensor must also include
+         android.hardware.sensor.proximity.xml -->
+    <!-- Devices that have low-latency audio stacks suitable for apps like
+         VoIP may include android.hardware.audio.low_latency.xml. ONLY apps
+         that meet the requirements specified in the CDD may include this. -->
+</permissions>
diff --git a/include/input/Input.h b/include/input/Input.h
index e778076..be79c59 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -184,6 +184,7 @@
     status_t setAxisValue(int32_t axis, float value);
 
     void scale(float scale);
+    void applyOffset(float xOffset, float yOffset);
 
     inline float getX() const {
         return getAxisValue(AMOTION_EVENT_AXIS_X);
diff --git a/include/media/openmax/OMX_AudioExt.h b/include/media/openmax/OMX_AudioExt.h
new file mode 100644
index 0000000..aa6e6d0
--- /dev/null
+++ b/include/media/openmax/OMX_AudioExt.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_AudioExt.h - OpenMax IL version 1.1.2
+ * The OMX_AudioExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access video items.
+ */
+
+#ifndef OMX_AudioExt_h
+#define OMX_AudioExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+typedef enum OMX_AUDIO_CODINGEXTTYPE {
+    OMX_AUDIO_CodingAndroidUnused = OMX_AUDIO_CodingKhronosExtensions + 0x00100000,
+    OMX_AUDIO_CodingAndroidAC3,         /**< AC3 encoded data */
+} OMX_AUDIO_CODINGEXTTYPE;
+
+typedef struct OMX_AUDIO_PARAM_ANDROID_AC3TYPE {
+    OMX_U32 nSize;                 /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< port that this structure applies to */
+    OMX_U32 nChannels;             /**< Number of channels */
+    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for
+                                        variable or unknown sampling rate. */
+} OMX_AUDIO_PARAM_ANDROID_AC3TYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_AudioExt_h */
+/* File EOF */
diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h
index d22df56..c47a885 100644
--- a/include/media/openmax/OMX_IndexExt.h
+++ b/include/media/openmax/OMX_IndexExt.h
@@ -57,6 +57,7 @@
 
     /* Audio parameters and configurations */
     OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,
+    OMX_IndexParamAudioAndroidAc3,                  /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */
 
     /* Image parameters and configurations */
     OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index bf4bf03..5584fb1 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -30,11 +30,15 @@
 class Parcel;
 class ISurfaceComposerClient;
 
+/*
+ * Used to communicate layer information between SurfaceFlinger and its clients.
+ */
 struct layer_state_t {
 
 
     enum {
-        eLayerHidden        = 0x01,
+        eLayerHidden        = 0x01,     // SURFACE_HIDDEN in SurfaceControl.java
+        eLayerOpaque        = 0x02,     // SURFACE_OPAQUE
     };
 
     enum {
@@ -47,6 +51,7 @@
         eVisibilityChanged          = 0x00000040,
         eLayerStackChanged          = 0x00000080,
         eCropChanged                = 0x00000100,
+        eOpacityChanged             = 0x00000200,
     };
 
     layer_state_t()
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 03bcf01..56e6d80 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -35,6 +35,7 @@
 
 #include <private/binder/binder_module.h>
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -1339,6 +1340,7 @@
 void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
     const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
 {
+    binder_size_t minOffset = 0;
     freeDataNoInit();
     mError = NO_ERROR;
     mData = const_cast<uint8_t*>(data);
@@ -1351,6 +1353,16 @@
     mNextObjectHint = 0;
     mOwner = relFunc;
     mOwnerCookie = relCookie;
+    for (size_t i = 0; i < mObjectsSize; i++) {
+        binder_size_t offset = mObjects[i];
+        if (offset < minOffset) {
+            ALOGE("%s: bad object offset %"PRIu64" < %"PRIu64"\n",
+                  __func__, (uint64_t)offset, (uint64_t)minOffset);
+            mObjectsSize = 0;
+            break;
+        }
+        minOffset = offset + sizeof(flat_binder_object);
+    }
     scanForFds();
 }
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index aafc4d2..2246f5f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -309,7 +309,12 @@
     layer_state_t* s = getLayerStateLocked(client, id);
     if (!s)
         return BAD_INDEX;
-    s->what |= layer_state_t::eVisibilityChanged;
+    if (mask & layer_state_t::eLayerOpaque) {
+        s->what |= layer_state_t::eOpacityChanged;
+    }
+    if (mask & layer_state_t::eLayerHidden) {
+        s->what |= layer_state_t::eVisibilityChanged;
+    }
     s->flags &= ~mask;
     s->flags |= (flags & mask);
     s->mask |= mask;
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 6f53996..ccbf52b 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -213,6 +213,11 @@
     scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
 }
 
+void PointerCoords::applyOffset(float xOffset, float yOffset) {
+    setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
+    setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
+}
+
 #ifdef HAVE_ANDROID_OS
 status_t PointerCoords::readFromParcel(Parcel* parcel) {
     bits = parcel->readInt64();
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index 03f94be..8512d6b 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -102,15 +102,6 @@
         }
     }
 
-    if (enabled) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "SensorFusion calling batch ident=%p ", ident);
-        // Activating a sensor in continuous mode is equivalent to calling batch with the default
-        // period and timeout equal to ZERO, followed by a call to activate.
-        mSensorDevice.batch(ident, mAcc.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
-        mSensorDevice.batch(ident, mMag.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
-        mSensorDevice.batch(ident, mGyro.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
-    }
-
     mSensorDevice.activate(ident, mAcc.getHandle(), enabled);
     mSensorDevice.activate(ident, mMag.getHandle(), enabled);
     mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
@@ -127,9 +118,10 @@
 }
 
 status_t SensorFusion::setDelay(void* ident, int64_t ns) {
-    mSensorDevice.setDelay(ident, mAcc.getHandle(), ns);
-    mSensorDevice.setDelay(ident, mMag.getHandle(), ms2ns(20));
-    mSensorDevice.setDelay(ident, mGyro.getHandle(), mTargetDelayNs);
+    // Call batch with timeout zero instead of setDelay().
+    mSensorDevice.batch(ident, mAcc.getHandle(), 0, ns, 0);
+    mSensorDevice.batch(ident, mMag.getHandle(), 0, ms2ns(20), 0);
+    mSensorDevice.batch(ident, mGyro.getHandle(), 0, mTargetDelayNs, 0);
     return NO_ERROR;
 }
 
diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h
index b8f360f..432adbc 100644
--- a/services/sensorservice/SensorFusion.h
+++ b/services/sensorservice/SensorFusion.h
@@ -37,7 +37,6 @@
 
 class SensorFusion : public Singleton<SensorFusion> {
     friend class Singleton<SensorFusion>;
-    static const nsecs_t DEFAULT_EVENTS_PERIOD = 200000000;  //  5 Hz
 
     SensorDevice& mSensorDevice;
     Sensor mAcc;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 61af51f..fcc9d78 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -64,7 +64,6 @@
         mName("unnamed"),
         mDebug(false),
         mFormat(PIXEL_FORMAT_NONE),
-        mOpaqueLayer(true),
         mTransactionFlags(0),
         mQueuedFrames(0),
         mCurrentTransform(0),
@@ -86,7 +85,9 @@
 
     uint32_t layerFlags = 0;
     if (flags & ISurfaceComposerClient::eHidden)
-        layerFlags = layer_state_t::eLayerHidden;
+        layerFlags |= layer_state_t::eLayerHidden;
+    if (flags & ISurfaceComposerClient::eOpaque)
+        layerFlags |= layer_state_t::eLayerOpaque;
 
     if (flags & ISurfaceComposerClient::eNonPremultiplied)
         mPremultipliedAlpha = false;
@@ -189,7 +190,6 @@
 
     mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
     mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
-    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
     mCurrentOpacity = getOpacityForFormat(format);
 
     mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
@@ -352,7 +352,7 @@
 
     // this gives us only the "orientation" component of the transform
     const State& s(getDrawingState());
-    if (!isOpaque() || s.alpha != 0xFF) {
+    if (!isOpaque(s) || s.alpha != 0xFF) {
         layer.setBlending(mPremultipliedAlpha ?
                 HWC_BLENDING_PREMULT :
                 HWC_BLENDING_COVERAGE);
@@ -596,7 +596,7 @@
     texCoords[3] = vec2(right, 1.0f - top);
 
     RenderEngine& engine(mFlinger->getRenderEngine());
-    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
+    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
     engine.drawMesh(mMesh);
     engine.disableBlending();
 }
@@ -656,7 +656,7 @@
     }
 }
 
-bool Layer::isOpaque() const
+bool Layer::isOpaque(const Layer::State& s) const
 {
     // if we don't have a buffer yet, we're translucent regardless of the
     // layer's opaque flag.
@@ -666,7 +666,7 @@
 
     // if the layer has the opaque flag, then we're always opaque,
     // otherwise we use the current buffer's format.
-    return mOpaqueLayer || mCurrentOpacity;
+    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
 }
 
 bool Layer::isProtected() const
@@ -954,7 +954,8 @@
         }
 
         // Capture the old state of the layer for comparisons later
-        const bool oldOpacity = isOpaque();
+        const State& s(getDrawingState());
+        const bool oldOpacity = isOpaque(s);
         sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
 
         struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
@@ -1122,12 +1123,11 @@
         }
 
         mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
-        if (oldOpacity != isOpaque()) {
+        if (oldOpacity != isOpaque(s)) {
             recomputeVisibleRegions = true;
         }
 
         // FIXME: postedRegion should be dirty & bounds
-        const Layer::State& s(getDrawingState());
         Region dirtyRegion(Rect(s.active.w, s.active.h));
 
         // transform the dirty region to window-manager space
@@ -1188,7 +1188,7 @@
             s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
             s.active.crop.left, s.active.crop.top,
             s.active.crop.right, s.active.crop.bottom,
-            isOpaque(), contentDirty,
+            isOpaque(s), contentDirty,
             s.alpha, s.flags,
             s.transform[0][0], s.transform[0][1],
             s.transform[1][0], s.transform[1][1],
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index ef4a7e9..ea65ded 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -149,8 +149,12 @@
 
     /*
      * isOpaque - true if this surface is opaque
+     *
+     * This takes into account the buffer format (i.e. whether or not the
+     * pixel format includes an alpha channel) and the "opaque" flag set
+     * on the layer.  It does not examine the current plane alpha value.
      */
-    virtual bool isOpaque() const;
+    virtual bool isOpaque(const Layer::State& s) const;
 
     /*
      * isSecure - true if this surface is secure, that is if it prevents
@@ -335,7 +339,6 @@
     String8 mName;
     mutable bool mDebug;
     PixelFormat mFormat;
-    bool mOpaqueLayer;
 
     // these are protected by an external lock
     State mCurrentState;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c00b034..86be6c3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1379,7 +1379,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isOpaque();
+            const bool translucent = !layer->isOpaque(s);
             Rect bounds(s.transform.transform(layer->computeBounds()));
             visibleRegion.set(bounds);
             if (!visibleRegion.isEmpty()) {
@@ -1624,7 +1624,7 @@
                         const Layer::State& state(layer->getDrawingState());
                         if ((cur->getHints() & HWC_HINT_CLEAR_FB)
                                 && i
-                                && layer->isOpaque() && (state.alpha == 0xFF)
+                                && layer->isOpaque(state) && (state.alpha == 0xFF)
                                 && hasGlesComposition) {
                             // never clear the very first layer since we're
                             // guaranteed the FB is already cleared
@@ -1868,7 +1868,9 @@
             if (layer->setTransparentRegionHint(s.transparentRegion))
                 flags |= eTraversalNeeded;
         }
-        if (what & layer_state_t::eVisibilityChanged) {
+        if ((what & layer_state_t::eVisibilityChanged) ||
+                (what & layer_state_t::eOpacityChanged)) {
+            // TODO: should we just use an eFlagsChanged for this?
             if (layer->setFlags(s.flags, s.mask))
                 flags |= eTraversalNeeded;
         }