diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index b360a26..4f605e0 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -67,6 +67,9 @@
         "SurfaceComposerClient.cpp",
         "SyncFeatures.cpp",
         "view/Surface.cpp",
+        "surfacetexture/SurfaceTexture.cpp",
+        "surfacetexture/ImageConsumer.cpp",
+        "surfacetexture/EGLConsumer.cpp",
     ],
 
     shared_libs: [
diff --git a/libs/gui/include/gui/surfacetexture/EGLConsumer.h b/libs/gui/include/gui/surfacetexture/EGLConsumer.h
new file mode 100644
index 0000000..444722b
--- /dev/null
+++ b/libs/gui/include/gui/surfacetexture/EGLConsumer.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <gui/BufferQueueDefs.h>
+#include <ui/FenceTime.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+class SurfaceTexture;
+
+/*
+ * EGLConsumer implements the parts of SurfaceTexture that deal with
+ * textures attached to an GL context.
+ */
+class EGLConsumer {
+public:
+    EGLConsumer();
+
+    /**
+     * updateTexImage acquires the most recently queued buffer, and sets the
+     * image contents of the target texture to it.
+     *
+     * This call may only be made while the OpenGL ES context to which the
+     * target texture belongs is bound to the calling thread.
+     *
+     * This calls doGLFenceWait to ensure proper synchronization.
+     */
+    status_t updateTexImage(SurfaceTexture& st);
+
+    /*
+     * releaseTexImage releases the texture acquired in updateTexImage().
+     * This is intended to be used in single buffer mode.
+     *
+     * This call may only be made while the OpenGL ES context to which the
+     * target texture belongs is bound to the calling thread.
+     */
+    status_t releaseTexImage(SurfaceTexture& st);
+
+    /**
+     * detachFromContext detaches the EGLConsumer from the calling thread's
+     * current OpenGL ES context.  This context must be the same as the context
+     * that was current for previous calls to updateTexImage.
+     *
+     * Detaching a EGLConsumer from an OpenGL ES context will result in the
+     * deletion of the OpenGL ES texture object into which the images were being
+     * streamed.  After a EGLConsumer has been detached from the OpenGL ES
+     * context calls to updateTexImage will fail returning INVALID_OPERATION
+     * until the EGLConsumer is attached to a new OpenGL ES context using the
+     * attachToContext method.
+     */
+    status_t detachFromContext(SurfaceTexture& st);
+
+    /**
+     * attachToContext attaches a EGLConsumer that is currently in the
+     * 'detached' state to the current OpenGL ES context.  A EGLConsumer is
+     * in the 'detached' state iff detachFromContext has successfully been
+     * called and no calls to attachToContext have succeeded since the last
+     * detachFromContext call.  Calls to attachToContext made on a
+     * EGLConsumer that is not in the 'detached' state will result in an
+     * INVALID_OPERATION error.
+     *
+     * The tex argument specifies the OpenGL ES texture object name in the
+     * new context into which the image contents will be streamed.  A successful
+     * call to attachToContext will result in this texture object being bound to
+     * the texture target and populated with the image contents that were
+     * current at the time of the last call to detachFromContext.
+     */
+    status_t attachToContext(uint32_t tex, SurfaceTexture& st);
+
+    /**
+     * onAcquireBufferLocked amends the ConsumerBase method to update the
+     * mEglSlots array in addition to the ConsumerBase behavior.
+     */
+    void onAcquireBufferLocked(BufferItem* item, SurfaceTexture& st);
+
+    /**
+     * onReleaseBufferLocked amends the ConsumerBase method to update the
+     * mEglSlots array in addition to the ConsumerBase.
+     */
+    void onReleaseBufferLocked(int slot);
+
+    /**
+     * onFreeBufferLocked frees up the given buffer slot. If the slot has been
+     * initialized this will release the reference to the GraphicBuffer in that
+     * slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
+     */
+    void onFreeBufferLocked(int slotIndex);
+
+    /**
+     * onAbandonLocked amends the ConsumerBase method to clear
+     * mCurrentTextureImage in addition to the ConsumerBase behavior.
+     */
+    void onAbandonLocked();
+
+protected:
+    struct PendingRelease {
+        PendingRelease()
+              : isPending(false),
+                currentTexture(-1),
+                graphicBuffer(),
+                display(nullptr),
+                fence(nullptr) {}
+
+        bool isPending;
+        int currentTexture;
+        sp<GraphicBuffer> graphicBuffer;
+        EGLDisplay display;
+        EGLSyncKHR fence;
+    };
+
+    /**
+     * This releases the buffer in the slot referenced by mCurrentTexture,
+     * then updates state to refer to the BufferItem, which must be a
+     * newly-acquired buffer. If pendingRelease is not null, the parameters
+     * which would have been passed to releaseBufferLocked upon the successful
+     * completion of the method will instead be returned to the caller, so that
+     * it may call releaseBufferLocked itself later.
+     */
+    status_t updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease,
+                                    SurfaceTexture& st);
+
+    /**
+     * Binds mTexName and the current buffer to mTexTarget.  Uses
+     * mCurrentTexture if it's set, mCurrentTextureImage if not.  If the
+     * bind succeeds, this calls doGLFenceWait.
+     */
+    status_t bindTextureImageLocked(SurfaceTexture& st);
+
+    /**
+     * Gets the current EGLDisplay and EGLContext values, and compares them
+     * to mEglDisplay and mEglContext.  If the fields have been previously
+     * set, the values must match; if not, the fields are set to the current
+     * values.
+     * The contextCheck argument is used to ensure that a GL context is
+     * properly set; when set to false, the check is not performed.
+     */
+    status_t checkAndUpdateEglStateLocked(SurfaceTexture& st, bool contextCheck = false);
+
+    /**
+     * EglImage is a utility class for tracking and creating EGLImageKHRs. There
+     * is primarily just one image per slot, but there is also special cases:
+     *  - For releaseTexImage, we use a debug image (mReleasedTexImage)
+     *  - After freeBuffer, we must still keep the current image/buffer
+     * Reference counting EGLImages lets us handle all these cases easily while
+     * also only creating new EGLImages from buffers when required.
+     */
+    class EglImage : public LightRefBase<EglImage> {
+    public:
+        EglImage(sp<GraphicBuffer> graphicBuffer);
+
+        /**
+         * createIfNeeded creates an EGLImage if required (we haven't created
+         * one yet, or the EGLDisplay or crop-rect has changed).
+         */
+        status_t createIfNeeded(EGLDisplay display, bool forceCreate = false);
+
+        /**
+         * This calls glEGLImageTargetTexture2DOES to bind the image to the
+         * texture in the specified texture target.
+         */
+        void bindToTextureTarget(uint32_t texTarget);
+
+        const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; }
+        const native_handle* graphicBufferHandle() {
+            return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle;
+        }
+
+    private:
+        // Only allow instantiation using ref counting.
+        friend class LightRefBase<EglImage>;
+        virtual ~EglImage();
+
+        // createImage creates a new EGLImage from a GraphicBuffer.
+        EGLImageKHR createImage(EGLDisplay dpy, const sp<GraphicBuffer>& graphicBuffer);
+
+        // Disallow copying
+        EglImage(const EglImage& rhs);
+        void operator=(const EglImage& rhs);
+
+        // mGraphicBuffer is the buffer that was used to create this image.
+        sp<GraphicBuffer> mGraphicBuffer;
+
+        // mEglImage is the EGLImage created from mGraphicBuffer.
+        EGLImageKHR mEglImage;
+
+        // mEGLDisplay is the EGLDisplay that was used to create mEglImage.
+        EGLDisplay mEglDisplay;
+
+        // mCropRect is the crop rectangle passed to EGL when mEglImage
+        // was created.
+        Rect mCropRect;
+    };
+
+    /**
+     * doGLFenceWaitLocked inserts a wait command into the OpenGL ES command
+     * stream to ensure that it is safe for future OpenGL ES commands to
+     * access the current texture buffer.
+     */
+    status_t doGLFenceWaitLocked(SurfaceTexture& st) const;
+
+    /**
+     * syncForReleaseLocked performs the synchronization needed to release the
+     * current slot from an OpenGL ES context.  If needed it will set the
+     * current slot's fence to guard against a producer accessing the buffer
+     * before the outstanding accesses have completed.
+     */
+    status_t syncForReleaseLocked(EGLDisplay dpy, SurfaceTexture& st);
+
+    /**
+     * returns a graphic buffer used when the texture image has been released
+     */
+    static sp<GraphicBuffer> getDebugTexImageBuffer();
+
+    /**
+     * The default consumer usage flags that EGLConsumer always sets on its
+     * BufferQueue instance; these will be OR:d with any additional flags passed
+     * from the EGLConsumer user. In particular, EGLConsumer will always
+     * consume buffers as hardware textures.
+     */
+    static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE;
+
+    /**
+     * mCurrentTextureImage is the EglImage/buffer of the current texture. It's
+     * possible that this buffer is not associated with any buffer slot, so we
+     * must track it separately in order to support the getCurrentBuffer method.
+     */
+    sp<EglImage> mCurrentTextureImage;
+
+    /**
+     * EGLSlot contains the information and object references that
+     * EGLConsumer maintains about a BufferQueue buffer slot.
+     */
+    struct EglSlot {
+        EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {}
+
+        /**
+         * mEglImage is the EGLImage created from mGraphicBuffer.
+         */
+        sp<EglImage> mEglImage;
+
+        /**
+         * mFence is the EGL sync object that must signal before the buffer
+         * associated with this buffer slot may be dequeued. It is initialized
+         * to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
+         * on a compile-time option) set to a new sync object in updateTexImage.
+         */
+        EGLSyncKHR mEglFence;
+    };
+
+    /**
+     * mEglDisplay is the EGLDisplay with which this EGLConsumer is currently
+     * associated.  It is intialized to EGL_NO_DISPLAY and gets set to the
+     * current display when updateTexImage is called for the first time and when
+     * attachToContext is called.
+     */
+    EGLDisplay mEglDisplay;
+
+    /**
+     * mEglContext is the OpenGL ES context with which this EGLConsumer is
+     * currently associated.  It is initialized to EGL_NO_CONTEXT and gets set
+     * to the current GL context when updateTexImage is called for the first
+     * time and when attachToContext is called.
+     */
+    EGLContext mEglContext;
+
+    /**
+     * mEGLSlots stores the buffers that have been allocated by the BufferQueue
+     * for each buffer slot.  It is initialized to null pointers, and gets
+     * filled in with the result of BufferQueue::acquire when the
+     * client dequeues a buffer from a
+     * slot that has not yet been used. The buffer allocated to a slot will also
+     * be replaced if the requested buffer usage or geometry differs from that
+     * of the buffer allocated to a slot.
+     */
+    EglSlot mEglSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];
+
+    /**
+     * protects static initialization
+     */
+    static Mutex sStaticInitLock;
+
+    /**
+     * mReleasedTexImageBuffer is a dummy buffer used when in single buffer
+     * mode and releaseTexImage() has been called
+     */
+    static sp<GraphicBuffer> sReleasedTexImageBuffer;
+    sp<EglImage> mReleasedTexImage;
+};
+
+} // namespace android
diff --git a/libs/gui/include/gui/surfacetexture/ImageConsumer.h b/libs/gui/include/gui/surfacetexture/ImageConsumer.h
new file mode 100644
index 0000000..35ae3d2
--- /dev/null
+++ b/libs/gui/include/gui/surfacetexture/ImageConsumer.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <cutils/compiler.h>
+#include <gui/BufferItem.h>
+#include <gui/BufferQueueDefs.h>
+#include <sys/cdefs.h>
+#include <system/graphics.h>
+
+namespace android {
+
+class SurfaceTexture;
+class DequeueBufferCallbacks;
+
+/*
+ * ImageConsumer implements the parts of SurfaceTexture that deal with
+ * images consumed by HWUI view system.
+ */
+class ImageConsumer {
+public:
+    typedef status_t (*SurfaceTexture_createReleaseFence)(bool useFenceSync, EGLSyncKHR* eglFence,
+                                                          EGLDisplay* display, int* releaseFence,
+                                                          void* fencePassThroughHandle);
+
+    typedef status_t (*SurfaceTexture_fenceWait)(int fence, void* fencePassThroughHandle);
+
+    sp<GraphicBuffer> dequeueBuffer(int* outSlotid, android_dataspace* outDataspace,
+                                    bool* outQueueEmpty, SurfaceTexture& cb,
+                                    SurfaceTexture_createReleaseFence createFence,
+                                    SurfaceTexture_fenceWait fenceWait,
+                                    void* fencePassThroughHandle);
+
+    /**
+     * onReleaseBufferLocked amends the ConsumerBase method to update the
+     * mImageSlots array in addition to the ConsumerBase.
+     */
+    void onReleaseBufferLocked(int slot);
+
+private:
+    /**
+     * ImageSlot contains the information and object references that
+     * ImageConsumer maintains about a BufferQueue buffer slot.
+     */
+    class ImageSlot {
+    public:
+        ImageSlot() : mEglFence(EGL_NO_SYNC_KHR) {}
+
+        inline EGLSyncKHR& eglFence() { return mEglFence; }
+
+    private:
+        /**
+         * mEglFence is the EGL sync object that must signal before the buffer
+         * associated with this buffer slot may be dequeued.
+         */
+        EGLSyncKHR mEglFence;
+    };
+
+    /**
+     * ImageConsumer stores the SkImages that have been allocated by the BufferQueue
+     * for each buffer slot.  It is initialized to null pointers, and gets
+     * filled in with the result of BufferQueue::acquire when the
+     * client dequeues a buffer from a
+     * slot that has not yet been used. The buffer allocated to a slot will also
+     * be replaced if the requested buffer usage or geometry differs from that
+     * of the buffer allocated to a slot.
+     */
+    ImageSlot mImageSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];
+};
+
+} /* namespace android */
diff --git a/libs/gui/include/gui/surfacetexture/SurfaceTexture.h b/libs/gui/include/gui/surfacetexture/SurfaceTexture.h
new file mode 100644
index 0000000..6eaa84e
--- /dev/null
+++ b/libs/gui/include/gui/surfacetexture/SurfaceTexture.h
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#pragma once
+
+#include <android/hardware_buffer.h>
+#include <gui/BufferQueueDefs.h>
+#include <gui/ConsumerBase.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <sys/cdefs.h>
+#include <system/graphics.h>
+#include <ui/FenceTime.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/Mutex.h>
+#include <utils/String8.h>
+
+#include "EGLConsumer.h"
+#include "ImageConsumer.h"
+
+namespace android {
+
+/*
+ * SurfaceTexture consumes buffers of graphics data from a BufferQueue,
+ * and makes them available to HWUI render thread as a SkImage and to
+ * an application GL render thread as an OpenGL texture.
+ *
+ * When attached to an application GL render thread, a typical usage
+ * pattern is to set up the SurfaceTexture with the
+ * desired options, and call updateTexImage() when a new frame is desired.
+ * If a new frame is available, the texture will be updated.  If not,
+ * the previous contents are retained.
+ *
+ * When attached to a HWUI render thread, the TextureView implementation
+ * calls dequeueBuffer, which either pulls a new buffer or returns the
+ * last cached buffer if BufferQueue is empty.
+ * When attached to HWUI render thread, SurfaceTexture is compatible to
+ * both Vulkan and GL drawing pipelines.
+ */
+class ANDROID_API SurfaceTexture : public ConsumerBase {
+public:
+    /**
+     * Callback function needed by dequeueBuffer. It creates a fence,
+     * that is signalled, when the previous buffer is no longer in use by HWUI
+     * and can be used by written by the producer.
+     */
+    typedef status_t (*SurfaceTexture_createReleaseFence)(bool useFenceSync, EGLSyncKHR* eglFence,
+                                                          EGLDisplay* display, int* releaseFence,
+                                                          void* passThroughHandle);
+
+    /**
+     * Callback function needed by dequeueBuffer. It waits for the new buffer
+     * fence to signal, before issuing any draw commands.
+     */
+    typedef status_t (*SurfaceTexture_fenceWait)(int fence, void* passThroughHandle);
+
+    enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES
+    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
+
+    /**
+     * SurfaceTexture constructs a new SurfaceTexture 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 SurfaceTexture may be detached from one OpenGL ES context and then
+     * attached to a different context using the detachFromContext and
+     * attachToContext methods, respectively. The intention of these methods is
+     * purely to allow a SurfaceTexture 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 SurfaceTexture 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 SurfaceTexture
+     * is created in a detached state, and attachToContext must be called before
+     * calls to updateTexImage.
+     */
+    SurfaceTexture(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, uint32_t textureTarget,
+                   bool useFenceSync, bool isControlledByApp);
+
+    SurfaceTexture(const sp<IGraphicBufferConsumer>& bq, uint32_t textureTarget, bool useFenceSync,
+                   bool isControlledByApp);
+
+    /**
+     * updateTexImage acquires the most recently queued buffer, and sets the
+     * image contents of the target texture to it.
+     *
+     * This call may only be made while the OpenGL ES context to which the
+     * target texture belongs is bound to the calling thread.
+     *
+     * This calls doGLFenceWait to ensure proper synchronization.
+     */
+    status_t updateTexImage();
+
+    /**
+     * releaseTexImage releases the texture acquired in updateTexImage().
+     * This is intended to be used in single buffer mode.
+     *
+     * This call may only be made while the OpenGL ES context to which the
+     * target texture belongs is bound to the calling thread.
+     */
+    status_t releaseTexImage();
+
+    /**
+     * getTransformMatrix retrieves the 4x4 texture coordinate transform matrix
+     * associated with the texture image set by the most recent call to
+     * updateTexImage.
+     *
+     * This transform matrix maps 2D homogeneous texture coordinates of the form
+     * (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture
+     * coordinate that should be used to sample that location from the texture.
+     * Sampling the texture outside of the range of this transform is undefined.
+     *
+     * This transform is necessary to compensate for transforms that the stream
+     * content producer may implicitly apply to the content. By forcing users of
+     * a SurfaceTexture to apply this transform we avoid performing an extra
+     * copy of the data that would be needed to hide the transform from the
+     * user.
+     *
+     * The matrix is stored in column-major order so that it may be passed
+     * directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv
+     * functions.
+     */
+    void getTransformMatrix(float mtx[16]);
+
+    /**
+     * Computes the transform matrix documented by getTransformMatrix
+     * from the BufferItem sub parts.
+     */
+    static void computeTransformMatrix(float outTransform[16], const sp<GraphicBuffer>& buf,
+                                       const Rect& cropRect, uint32_t transform, bool filtering);
+
+    /**
+     * Scale the crop down horizontally or vertically such that it has the
+     * same aspect ratio as the buffer does.
+     */
+    static Rect scaleDownCrop(const Rect& crop, uint32_t bufferWidth, uint32_t bufferHeight);
+
+    /**
+     * getTimestamp retrieves the timestamp associated with the texture image
+     * set by the most recent call to updateTexImage.
+     *
+     * The timestamp is in nanoseconds, and is monotonically increasing. Its
+     * other semantics (zero point, etc) are source-dependent and should be
+     * documented by the source.
+     */
+    int64_t getTimestamp();
+
+    /**
+     * getDataSpace retrieves the DataSpace associated with the texture image
+     * set by the most recent call to updateTexImage.
+     */
+    android_dataspace getCurrentDataSpace();
+
+    /**
+     * getFrameNumber retrieves the frame number associated with the texture
+     * image set by the most recent call to updateTexImage.
+     *
+     * The frame number is an incrementing counter set to 0 at the creation of
+     * the BufferQueue associated with this consumer.
+     */
+    uint64_t getFrameNumber();
+
+    /**
+     * setDefaultBufferSize is used to set the size of buffers returned by
+     * requestBuffers when a with and height of zero is requested.
+     * A call to setDefaultBufferSize() may trigger requestBuffers() to
+     * be called from the client.
+     * The width and height parameters must be no greater than the minimum of
+     * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
+     * An error due to invalid dimensions might not be reported until
+     * updateTexImage() is called.
+     */
+    status_t setDefaultBufferSize(uint32_t width, uint32_t height);
+
+    /**
+     * setFilteringEnabled sets whether the transform matrix should be computed
+     * for use with bilinear filtering.
+     */
+    void setFilteringEnabled(bool enabled);
+
+    /**
+     * getCurrentTextureTarget returns the texture target of the current
+     * texture as returned by updateTexImage().
+     */
+    uint32_t getCurrentTextureTarget() const;
+
+    /**
+     * getCurrentCrop returns the cropping rectangle of the current buffer.
+     */
+    Rect getCurrentCrop() const;
+
+    /**
+     * getCurrentTransform returns the transform of the current buffer.
+     */
+    uint32_t getCurrentTransform() const;
+
+    /**
+     * getCurrentScalingMode returns the scaling mode of the current buffer.
+     */
+    uint32_t getCurrentScalingMode() const;
+
+    /**
+     * getCurrentFence returns the fence indicating when the current buffer is
+     * ready to be read from.
+     */
+    sp<Fence> getCurrentFence() const;
+
+    /**
+     * getCurrentFence returns the FenceTime indicating when the current
+     * buffer is ready to be read from.
+     */
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const;
+
+    /**
+     * setConsumerUsageBits overrides the ConsumerBase method to OR
+     * DEFAULT_USAGE_FLAGS to usage.
+     */
+    status_t setConsumerUsageBits(uint64_t usage);
+
+    /**
+     * detachFromContext detaches the SurfaceTexture from the calling thread's
+     * current OpenGL ES context.  This context must be the same as the context
+     * that was current for previous calls to updateTexImage.
+     *
+     * Detaching a SurfaceTexture from an OpenGL ES context will result in the
+     * deletion of the OpenGL ES texture object into which the images were being
+     * streamed.  After a SurfaceTexture has been detached from the OpenGL ES
+     * context calls to updateTexImage will fail returning INVALID_OPERATION
+     * until the SurfaceTexture is attached to a new OpenGL ES context using the
+     * attachToContext method.
+     */
+    status_t detachFromContext();
+
+    /**
+     * attachToContext attaches a SurfaceTexture that is currently in the
+     * 'detached' state to the current OpenGL ES context.  A SurfaceTexture is
+     * in the 'detached' state iff detachFromContext has successfully been
+     * called and no calls to attachToContext have succeeded since the last
+     * detachFromContext call.  Calls to attachToContext made on a
+     * SurfaceTexture that is not in the 'detached' state will result in an
+     * INVALID_OPERATION error.
+     *
+     * The tex argument specifies the OpenGL ES texture object name in the
+     * new context into which the image contents will be streamed.  A successful
+     * call to attachToContext will result in this texture object being bound to
+     * the texture target and populated with the image contents that were
+     * current at the time of the last call to detachFromContext.
+     */
+    status_t attachToContext(uint32_t tex);
+
+    sp<GraphicBuffer> dequeueBuffer(int* outSlotid, android_dataspace* outDataspace,
+                                    float* outTransformMatrix, bool* outQueueEmpty,
+                                    SurfaceTexture_createReleaseFence createFence,
+                                    SurfaceTexture_fenceWait fenceWait,
+                                    void* fencePassThroughHandle);
+
+    /**
+     * takeConsumerOwnership attaches a SurfaceTexture that is currently in the
+     * 'detached' state to a consumer context (usually HWUI RenderThread).
+     */
+    void takeConsumerOwnership();
+
+    /**
+     * releaseConsumerOwnership detaches a SurfaceTexture from a consumer
+     * context (usually HWUI RenderThread).
+     */
+    void releaseConsumerOwnership();
+
+protected:
+    /**
+     * abandonLocked overrides the ConsumerBase method to clear
+     * mCurrentTextureImage in addition to the ConsumerBase behavior.
+     */
+    virtual void abandonLocked();
+
+    /**
+     * dumpLocked overrides the ConsumerBase method to dump SurfaceTexture-
+     * specific info in addition to the ConsumerBase behavior.
+     */
+    virtual void dumpLocked(String8& result, const char* prefix) const override;
+
+    /**
+     * acquireBufferLocked overrides the ConsumerBase method to update the
+     * mEglSlots array in addition to the ConsumerBase behavior.
+     */
+    virtual status_t acquireBufferLocked(BufferItem* item, nsecs_t presentWhen,
+                                         uint64_t maxFrameNumber = 0) override;
+
+    /**
+     * releaseBufferLocked overrides the ConsumerBase method to update the
+     * mEglSlots array in addition to the ConsumerBase.
+     */
+    virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer,
+                                         EGLDisplay display, EGLSyncKHR eglFence) override;
+
+    /**
+     * freeBufferLocked frees up the given buffer slot. If the slot has been
+     * initialized this will release the reference to the GraphicBuffer in that
+     * slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
+     *
+     * This method must be called with mMutex locked.
+     */
+    virtual void freeBufferLocked(int slotIndex);
+
+    /**
+     * computeCurrentTransformMatrixLocked computes the transform matrix for the
+     * current texture.  It uses mCurrentTransform and the current GraphicBuffer
+     * to compute this matrix and stores it in mCurrentTransformMatrix.
+     * mCurrentTextureImage must not be NULL.
+     */
+    void computeCurrentTransformMatrixLocked();
+
+    /**
+     * The default consumer usage flags that SurfaceTexture always sets on its
+     * BufferQueue instance; these will be OR:d with any additional flags passed
+     * from the SurfaceTexture user. In particular, SurfaceTexture will always
+     * consume buffers as hardware textures.
+     */
+    static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE;
+
+    /**
+     * mCurrentCrop is the crop rectangle that applies to the current texture.
+     * It gets set each time updateTexImage is called.
+     */
+    Rect mCurrentCrop;
+
+    /**
+     * mCurrentTransform is the transform identifier for the current texture. It
+     * gets set each time updateTexImage is called.
+     */
+    uint32_t mCurrentTransform;
+
+    /**
+     * mCurrentScalingMode is the scaling mode for the current texture. It gets
+     * set each time updateTexImage is called.
+     */
+    uint32_t mCurrentScalingMode;
+
+    /**
+     * mCurrentFence is the fence received from BufferQueue in updateTexImage.
+     */
+    sp<Fence> mCurrentFence;
+
+    /**
+     * The FenceTime wrapper around mCurrentFence.
+     */
+    std::shared_ptr<FenceTime> mCurrentFenceTime{FenceTime::NO_FENCE};
+
+    /**
+     * mCurrentTransformMatrix is the transform matrix for the current texture.
+     * It gets computed by computeTransformMatrix each time updateTexImage is
+     * called.
+     */
+    float mCurrentTransformMatrix[16];
+
+    /**
+     * mCurrentTimestamp is the timestamp for the current texture. It
+     * gets set each time updateTexImage is called.
+     */
+    int64_t mCurrentTimestamp;
+
+    /**
+     * mCurrentDataSpace is the dataspace for the current texture. It
+     * gets set each time updateTexImage is called.
+     */
+    android_dataspace mCurrentDataSpace;
+
+    /**
+     * mCurrentFrameNumber is the frame counter for the current texture.
+     * It gets set each time updateTexImage is called.
+     */
+    uint64_t mCurrentFrameNumber;
+
+    uint32_t mDefaultWidth, mDefaultHeight;
+
+    /**
+     * mFilteringEnabled indicates whether the transform matrix is computed for
+     * use with bilinear filtering. It defaults to true and is changed by
+     * setFilteringEnabled().
+     */
+    bool mFilteringEnabled;
+
+    /**
+     * mTexName is the name of the OpenGL texture to which streamed images will
+     * be bound when updateTexImage is called. It is set at construction time
+     * and can be changed with a call to attachToContext.
+     */
+    uint32_t mTexName;
+
+    /**
+     * mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync
+     * extension should be used to prevent buffers from being dequeued before
+     * it's safe for them to be written. It gets set at construction time and
+     * never changes.
+     */
+    const bool mUseFenceSync;
+
+    /**
+     * mTexTarget is the GL texture target with which the GL texture object is
+     * associated.  It is set in the constructor and never changed.  It is
+     * almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android
+     * Browser.  In that case it is set to GL_TEXTURE_2D to allow
+     * glCopyTexSubImage to read from the texture.  This is a hack to work
+     * around a GL driver limitation on the number of FBO attachments, which the
+     * browser's tile cache exceeds.
+     */
+    const uint32_t mTexTarget;
+
+    /**
+     * mCurrentTexture is the buffer slot index of the buffer that is currently
+     * bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
+     * indicating that no buffer slot is currently bound to the texture. Note,
+     * however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+     * that no buffer is bound to the texture. A call to setBufferCount will
+     * reset mCurrentTexture to INVALID_BUFFER_SLOT.
+     */
+    int mCurrentTexture;
+
+    enum class OpMode { detached, attachedToConsumer, attachedToGL };
+    /**
+     * mOpMode indicates whether the SurfaceTexture is currently attached to
+     * an OpenGL ES context or the consumer context.  For legacy reasons, this
+     * is initialized to, "attachedToGL" indicating that the SurfaceTexture is
+     * considered to be attached to whatever GL context is current at the time
+     * of the first updateTexImage call.
+     * It is set to "detached" by detachFromContext, and then set to
+     * "attachedToGL" again by attachToContext.
+     * takeConsumerOwnership/releaseConsumerOwnership are used to attach/detach
+     * from a consumer context - usually HWUI RenderThread.
+     */
+    OpMode mOpMode;
+
+    /**
+     * mEGLConsumer has SurfaceTexture logic used when attached to GL context.
+     */
+    EGLConsumer mEGLConsumer;
+
+    /**
+     * mImageConsumer has SurfaceTexture logic used when attached to a consumer
+     * context (usually HWUI RenderThread).
+     */
+    ImageConsumer mImageConsumer;
+
+    friend class ImageConsumer;
+    friend class EGLConsumer;
+};
+
+// ----------------------------------------------------------------------------
+} // namespace android
diff --git a/libs/gui/include/gui/surfacetexture/surface_texture_platform.h b/libs/gui/include/gui/surfacetexture/surface_texture_platform.h
new file mode 100644
index 0000000..72f98ad
--- /dev/null
+++ b/libs/gui/include/gui/surfacetexture/surface_texture_platform.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#ifndef _ANDROID_GRAPHICS_SURFACE_TEXTURE_PLATFORM_H
+#define _ANDROID_GRAPHICS_SURFACE_TEXTURE_PLATFORM_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <system/graphics.h>
+
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/surfacetexture/SurfaceTexture.h>
+
+// This file provides a facade API on top of SurfaceTexture, which avoids using
+// C++ types. This is still a C++ unstable API though. Ideally features here
+// will be exposed via public NDK API and this file will be deleted.
+
+struct ASurfaceTexture {
+    android::sp<android::SurfaceTexture> consumer;
+    android::sp<android::IGraphicBufferProducer> producer;
+};
+
+namespace android {
+
+/**
+ * ASurfaceTexture_getCurrentTextureTarget returns the texture target of the
+ * current texture.
+ */
+unsigned int ASurfaceTexture_getCurrentTextureTarget(ASurfaceTexture* st);
+
+/**
+ * ASurfaceTexture_takeConsumerOwnership attaches an ASurfaceTexture that is
+ * currently in the 'detached' state to a consumer context.
+ */
+void ASurfaceTexture_takeConsumerOwnership(ASurfaceTexture* st);
+
+/**
+ * ASurfaceTexture_releaseConsumerOwnership detaches a SurfaceTexture from
+ * a consumer context.
+ */
+void ASurfaceTexture_releaseConsumerOwnership(ASurfaceTexture* st);
+
+/**
+ * Callback function needed by ASurfaceTexture_dequeueBuffer. It creates a
+ * fence that is signalled when the previous buffer is no longer in use by the
+ * consumer (usually HWUI RenderThread) and can be written to by the producer.
+ */
+typedef int (*ASurfaceTexture_createReleaseFence)(bool useFenceSync, EGLSyncKHR* eglFence,
+                                                  EGLDisplay* display, int* releaseFence,
+                                                  void* fencePassThroughHandle);
+
+/**
+ * Callback function needed by ASurfaceTexture_dequeueBuffer. It waits for the
+ * new buffer fence to signal before issuing any draw commands.
+ */
+typedef int (*ASurfaceTexture_fenceWait)(int fence, void* fencePassThroughHandle);
+
+/**
+ * ASurfaceTexture_dequeueBuffer returns the next available AHardwareBuffer.
+ */
+AHardwareBuffer* ASurfaceTexture_dequeueBuffer(ASurfaceTexture* st, int* outSlotid,
+                                               android_dataspace* outDataspace,
+                                               float* outTransformMatrix, bool* outNewContent,
+                                               ASurfaceTexture_createReleaseFence createFence,
+                                               ASurfaceTexture_fenceWait fenceWait,
+                                               void* fencePassThroughHandle);
+
+/**
+ * ASurfaceTexture_create creates an ASurfaceTexture, which is
+ * a simple struct containing a SurfaceTexture and an IGraphicBufferProducer.
+ */
+ASurfaceTexture* ASurfaceTexture_create(sp<SurfaceTexture> consumer,
+                                        sp<IGraphicBufferProducer> producer);
+
+} // namespace android
+
+#endif // _ANDROID_GRAPHICS_SURFACE_TEXTURE_PLATFORM_H
diff --git a/libs/gui/surfacetexture/EGLConsumer.cpp b/libs/gui/surfacetexture/EGLConsumer.cpp
new file mode 100644
index 0000000..1f0f52c
--- /dev/null
+++ b/libs/gui/surfacetexture/EGLConsumer.cpp
@@ -0,0 +1,674 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <cutils/compiler.h>
+#include <gui/BufferItem.h>
+#include <gui/BufferQueue.h>
+#include <gui/surfacetexture/EGLConsumer.h>
+#include <gui/surfacetexture/SurfaceTexture.h>
+#include <inttypes.h>
+#include <private/gui/SyncFeatures.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/Trace.h>
+
+#define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content"
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+
+namespace android {
+
+// Macros for including the SurfaceTexture name in log messages
+#define EGC_LOGV(x, ...) ALOGV("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+#define EGC_LOGD(x, ...) ALOGD("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+#define EGC_LOGW(x, ...) ALOGW("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+#define EGC_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+
+static const struct {
+    uint32_t width, height;
+    char const* bits;
+} kDebugData = {15, 12,
+                "_______________"
+                "_______________"
+                "_____XX_XX_____"
+                "__X_X_____X_X__"
+                "__X_XXXXXXX_X__"
+                "__XXXXXXXXXXX__"
+                "___XX_XXX_XX___"
+                "____XXXXXXX____"
+                "_____X___X_____"
+                "____X_____X____"
+                "_______________"
+                "_______________"};
+
+Mutex EGLConsumer::sStaticInitLock;
+sp<GraphicBuffer> EGLConsumer::sReleasedTexImageBuffer;
+
+static bool hasEglProtectedContentImpl() {
+    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
+    size_t cropExtLen = strlen(PROT_CONTENT_EXT_STR);
+    size_t extsLen = strlen(exts);
+    bool equal = !strcmp(PROT_CONTENT_EXT_STR, exts);
+    bool atStart = !strncmp(PROT_CONTENT_EXT_STR " ", exts, cropExtLen + 1);
+    bool atEnd = (cropExtLen + 1) < extsLen &&
+            !strcmp(" " PROT_CONTENT_EXT_STR, exts + extsLen - (cropExtLen + 1));
+    bool inMiddle = strstr(exts, " " PROT_CONTENT_EXT_STR " ");
+    return equal || atStart || atEnd || inMiddle;
+}
+
+static bool hasEglProtectedContent() {
+    // Only compute whether the extension is present once the first time this
+    // function is called.
+    static bool hasIt = hasEglProtectedContentImpl();
+    return hasIt;
+}
+
+EGLConsumer::EGLConsumer() : mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT) {}
+
+status_t EGLConsumer::updateTexImage(SurfaceTexture& st) {
+    // Make sure the EGL state is the same as in previous calls.
+    status_t err = checkAndUpdateEglStateLocked(st);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    BufferItem item;
+
+    // Acquire the next buffer.
+    // In asynchronous mode the list is guaranteed to be one buffer
+    // deep, while in synchronous mode we use the oldest buffer.
+    err = st.acquireBufferLocked(&item, 0);
+    if (err != NO_ERROR) {
+        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
+            // We always bind the texture even if we don't update its contents.
+            EGC_LOGV("updateTexImage: no buffers were available");
+            glBindTexture(st.mTexTarget, st.mTexName);
+            err = NO_ERROR;
+        } else {
+            EGC_LOGE("updateTexImage: acquire failed: %s (%d)", strerror(-err), err);
+        }
+        return err;
+    }
+
+    // Release the previous buffer.
+    err = updateAndReleaseLocked(item, nullptr, st);
+    if (err != NO_ERROR) {
+        // We always bind the texture.
+        glBindTexture(st.mTexTarget, st.mTexName);
+        return err;
+    }
+
+    // Bind the new buffer to the GL texture, and wait until it's ready.
+    return bindTextureImageLocked(st);
+}
+
+status_t EGLConsumer::releaseTexImage(SurfaceTexture& st) {
+    // Make sure the EGL state is the same as in previous calls.
+    status_t err = NO_ERROR;
+
+    // if we're detached, no need to validate EGL's state -- we won't use it.
+    if (st.mOpMode == SurfaceTexture::OpMode::attachedToGL) {
+        err = checkAndUpdateEglStateLocked(st, true);
+        if (err != NO_ERROR) {
+            return err;
+        }
+    }
+
+    // Update the EGLConsumer state.
+    int buf = st.mCurrentTexture;
+    if (buf != BufferQueue::INVALID_BUFFER_SLOT) {
+        EGC_LOGV("releaseTexImage: (slot=%d, mOpMode=%d)", buf, (int)st.mOpMode);
+
+        // if we're detached, we just use the fence that was created in
+        // detachFromContext() so... basically, nothing more to do here.
+        if (st.mOpMode == SurfaceTexture::OpMode::attachedToGL) {
+            // Do whatever sync ops we need to do before releasing the slot.
+            err = syncForReleaseLocked(mEglDisplay, st);
+            if (err != NO_ERROR) {
+                EGC_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err);
+                return err;
+            }
+        }
+
+        err = st.releaseBufferLocked(buf, st.mSlots[buf].mGraphicBuffer, mEglDisplay,
+                                     EGL_NO_SYNC_KHR);
+        if (err < NO_ERROR) {
+            EGC_LOGE("releaseTexImage: failed to release buffer: %s (%d)", strerror(-err), err);
+            return err;
+        }
+
+        if (mReleasedTexImage == nullptr) {
+            mReleasedTexImage = new EglImage(getDebugTexImageBuffer());
+        }
+
+        st.mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
+        mCurrentTextureImage = mReleasedTexImage;
+        st.mCurrentCrop.makeInvalid();
+        st.mCurrentTransform = 0;
+        st.mCurrentTimestamp = 0;
+        st.mCurrentDataSpace = HAL_DATASPACE_UNKNOWN;
+        st.mCurrentFence = Fence::NO_FENCE;
+        st.mCurrentFenceTime = FenceTime::NO_FENCE;
+
+        // detached, don't touch the texture (and we may not even have an
+        // EGLDisplay here.
+        if (st.mOpMode == SurfaceTexture::OpMode::attachedToGL) {
+            // This binds a dummy buffer (mReleasedTexImage).
+            status_t result = bindTextureImageLocked(st);
+            if (result != NO_ERROR) {
+                return result;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+sp<GraphicBuffer> EGLConsumer::getDebugTexImageBuffer() {
+    Mutex::Autolock _l(sStaticInitLock);
+    if (CC_UNLIKELY(sReleasedTexImageBuffer == nullptr)) {
+        // The first time, create the debug texture in case the application
+        // continues to use it.
+        sp<GraphicBuffer> buffer =
+                new GraphicBuffer(kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
+                                  GraphicBuffer::USAGE_SW_WRITE_RARELY,
+                                  "[EGLConsumer debug texture]");
+        uint32_t* bits;
+        buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
+        uint32_t stride = buffer->getStride();
+        uint32_t height = buffer->getHeight();
+        memset(bits, 0, stride * height * 4);
+        for (uint32_t y = 0; y < kDebugData.height; y++) {
+            for (uint32_t x = 0; x < kDebugData.width; x++) {
+                bits[x] = (kDebugData.bits[y + kDebugData.width + x] == 'X') ? 0xFF000000
+                                                                             : 0xFFFFFFFF;
+            }
+            bits += stride;
+        }
+        buffer->unlock();
+        sReleasedTexImageBuffer = buffer;
+    }
+    return sReleasedTexImageBuffer;
+}
+
+void EGLConsumer::onAcquireBufferLocked(BufferItem* item, SurfaceTexture& st) {
+    // If item->mGraphicBuffer is not null, this buffer has not been acquired
+    // before, so any prior EglImage created is using a stale buffer. This
+    // replaces any old EglImage with a new one (using the new buffer).
+    int slot = item->mSlot;
+    if (item->mGraphicBuffer != nullptr || mEglSlots[slot].mEglImage.get() == nullptr) {
+        mEglSlots[slot].mEglImage = new EglImage(st.mSlots[slot].mGraphicBuffer);
+    }
+}
+
+void EGLConsumer::onReleaseBufferLocked(int buf) {
+    mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
+}
+
+status_t EGLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease,
+                                             SurfaceTexture& st) {
+    status_t err = NO_ERROR;
+
+    int slot = item.mSlot;
+
+    if (st.mOpMode != SurfaceTexture::OpMode::attachedToGL) {
+        EGC_LOGE("updateAndRelease: EGLConsumer is not attached to an OpenGL "
+                 "ES context");
+        st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
+        return INVALID_OPERATION;
+    }
+
+    // Confirm state.
+    err = checkAndUpdateEglStateLocked(st);
+    if (err != NO_ERROR) {
+        st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
+        return err;
+    }
+
+    // Ensure we have a valid EglImageKHR for the slot, creating an EglImage
+    // if nessessary, for the gralloc buffer currently in the slot in
+    // ConsumerBase.
+    // We may have to do this even when item.mGraphicBuffer == NULL (which
+    // means the buffer was previously acquired).
+    err = mEglSlots[slot].mEglImage->createIfNeeded(mEglDisplay);
+    if (err != NO_ERROR) {
+        EGC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", mEglDisplay,
+                 slot);
+        st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
+        return UNKNOWN_ERROR;
+    }
+
+    // Do whatever sync ops we need to do before releasing the old slot.
+    if (slot != st.mCurrentTexture) {
+        err = syncForReleaseLocked(mEglDisplay, st);
+        if (err != NO_ERROR) {
+            // Release the buffer we just acquired.  It's not safe to
+            // release the old buffer, so instead we just drop the new frame.
+            // As we are still under lock since acquireBuffer, it is safe to
+            // release by slot.
+            st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, mEglDisplay,
+                                   EGL_NO_SYNC_KHR);
+            return err;
+        }
+    }
+
+    EGC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", st.mCurrentTexture,
+             mCurrentTextureImage != nullptr ? mCurrentTextureImage->graphicBufferHandle()
+                                             : nullptr,
+             slot, st.mSlots[slot].mGraphicBuffer->handle);
+
+    // Hang onto the pointer so that it isn't freed in the call to
+    // releaseBufferLocked() if we're in shared buffer mode and both buffers are
+    // the same.
+    sp<EglImage> nextTextureImage = mEglSlots[slot].mEglImage;
+
+    // release old buffer
+    if (st.mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
+        if (pendingRelease == nullptr) {
+            status_t status =
+                    st.releaseBufferLocked(st.mCurrentTexture,
+                                           mCurrentTextureImage->graphicBuffer(), mEglDisplay,
+                                           mEglSlots[st.mCurrentTexture].mEglFence);
+            if (status < NO_ERROR) {
+                EGC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status),
+                         status);
+                err = status;
+                // keep going, with error raised [?]
+            }
+        } else {
+            pendingRelease->currentTexture = st.mCurrentTexture;
+            pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer();
+            pendingRelease->display = mEglDisplay;
+            pendingRelease->fence = mEglSlots[st.mCurrentTexture].mEglFence;
+            pendingRelease->isPending = true;
+        }
+    }
+
+    // Update the EGLConsumer state.
+    st.mCurrentTexture = slot;
+    mCurrentTextureImage = nextTextureImage;
+    st.mCurrentCrop = item.mCrop;
+    st.mCurrentTransform = item.mTransform;
+    st.mCurrentScalingMode = item.mScalingMode;
+    st.mCurrentTimestamp = item.mTimestamp;
+    st.mCurrentDataSpace = item.mDataSpace;
+    st.mCurrentFence = item.mFence;
+    st.mCurrentFenceTime = item.mFenceTime;
+    st.mCurrentFrameNumber = item.mFrameNumber;
+
+    st.computeCurrentTransformMatrixLocked();
+
+    return err;
+}
+
+status_t EGLConsumer::bindTextureImageLocked(SurfaceTexture& st) {
+    if (mEglDisplay == EGL_NO_DISPLAY) {
+        ALOGE("bindTextureImage: invalid display");
+        return INVALID_OPERATION;
+    }
+
+    GLenum error;
+    while ((error = glGetError()) != GL_NO_ERROR) {
+        EGC_LOGW("bindTextureImage: clearing GL error: %#04x", error);
+    }
+
+    glBindTexture(st.mTexTarget, st.mTexName);
+    if (st.mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) {
+        EGC_LOGE("bindTextureImage: no currently-bound texture");
+        return NO_INIT;
+    }
+
+    status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay);
+    if (err != NO_ERROR) {
+        EGC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", mEglDisplay,
+                 st.mCurrentTexture);
+        return UNKNOWN_ERROR;
+    }
+    mCurrentTextureImage->bindToTextureTarget(st.mTexTarget);
+
+    // In the rare case that the display is terminated and then initialized
+    // again, we can't detect that the display changed (it didn't), but the
+    // image is invalid. In this case, repeat the exact same steps while
+    // forcing the creation of a new image.
+    if ((error = glGetError()) != GL_NO_ERROR) {
+        glBindTexture(st.mTexTarget, st.mTexName);
+        status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay, true);
+        if (result != NO_ERROR) {
+            EGC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", mEglDisplay,
+                     st.mCurrentTexture);
+            return UNKNOWN_ERROR;
+        }
+        mCurrentTextureImage->bindToTextureTarget(st.mTexTarget);
+        if ((error = glGetError()) != GL_NO_ERROR) {
+            EGC_LOGE("bindTextureImage: error binding external image: %#04x", error);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    // Wait for the new buffer to be ready.
+    return doGLFenceWaitLocked(st);
+}
+
+status_t EGLConsumer::checkAndUpdateEglStateLocked(SurfaceTexture& st, bool contextCheck) {
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLContext ctx = eglGetCurrentContext();
+
+    if (!contextCheck) {
+        // if this is the first time we're called, mEglDisplay/mEglContext have
+        // never been set, so don't error out (below).
+        if (mEglDisplay == EGL_NO_DISPLAY) {
+            mEglDisplay = dpy;
+        }
+        if (mEglContext == EGL_NO_CONTEXT) {
+            mEglContext = ctx;
+        }
+    }
+
+    if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
+        EGC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
+        return INVALID_OPERATION;
+    }
+
+    if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) {
+        EGC_LOGE("checkAndUpdateEglState: invalid current EGLContext");
+        return INVALID_OPERATION;
+    }
+
+    mEglDisplay = dpy;
+    mEglContext = ctx;
+    return NO_ERROR;
+}
+
+status_t EGLConsumer::detachFromContext(SurfaceTexture& st) {
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLContext ctx = eglGetCurrentContext();
+
+    if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) {
+        EGC_LOGE("detachFromContext: invalid current EGLDisplay");
+        return INVALID_OPERATION;
+    }
+
+    if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) {
+        EGC_LOGE("detachFromContext: invalid current EGLContext");
+        return INVALID_OPERATION;
+    }
+
+    if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) {
+        status_t err = syncForReleaseLocked(dpy, st);
+        if (err != OK) {
+            return err;
+        }
+
+        glDeleteTextures(1, &st.mTexName);
+    }
+
+    mEglDisplay = EGL_NO_DISPLAY;
+    mEglContext = EGL_NO_CONTEXT;
+
+    return OK;
+}
+
+status_t EGLConsumer::attachToContext(uint32_t tex, SurfaceTexture& st) {
+    // Initialize mCurrentTextureImage if there is a current buffer from past
+    // attached state.
+    int slot = st.mCurrentTexture;
+    if (slot != BufferItem::INVALID_BUFFER_SLOT) {
+        if (!mEglSlots[slot].mEglImage.get()) {
+            mEglSlots[slot].mEglImage = new EglImage(st.mSlots[slot].mGraphicBuffer);
+        }
+        mCurrentTextureImage = mEglSlots[slot].mEglImage;
+    }
+
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLContext ctx = eglGetCurrentContext();
+
+    if (dpy == EGL_NO_DISPLAY) {
+        EGC_LOGE("attachToContext: invalid current EGLDisplay");
+        return INVALID_OPERATION;
+    }
+
+    if (ctx == EGL_NO_CONTEXT) {
+        EGC_LOGE("attachToContext: invalid current EGLContext");
+        return INVALID_OPERATION;
+    }
+
+    // We need to bind the texture regardless of whether there's a current
+    // buffer.
+    glBindTexture(st.mTexTarget, GLuint(tex));
+
+    mEglDisplay = dpy;
+    mEglContext = ctx;
+    st.mTexName = tex;
+    st.mOpMode = SurfaceTexture::OpMode::attachedToGL;
+
+    if (mCurrentTextureImage != nullptr) {
+        // This may wait for a buffer a second time. This is likely required if
+        // this is a different context, since otherwise the wait could be skipped
+        // by bouncing through another context. For the same context the extra
+        // wait is redundant.
+        status_t err = bindTextureImageLocked(st);
+        if (err != NO_ERROR) {
+            return err;
+        }
+    }
+
+    return OK;
+}
+
+status_t EGLConsumer::syncForReleaseLocked(EGLDisplay dpy, SurfaceTexture& st) {
+    EGC_LOGV("syncForReleaseLocked");
+
+    if (st.mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
+        if (SyncFeatures::getInstance().useNativeFenceSync()) {
+            EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
+            if (sync == EGL_NO_SYNC_KHR) {
+                EGC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", eglGetError());
+                return UNKNOWN_ERROR;
+            }
+            glFlush();
+            int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync);
+            eglDestroySyncKHR(dpy, sync);
+            if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
+                EGC_LOGE("syncForReleaseLocked: error dup'ing native fence "
+                         "fd: %#x",
+                         eglGetError());
+                return UNKNOWN_ERROR;
+            }
+            sp<Fence> fence(new Fence(fenceFd));
+            status_t err = st.addReleaseFenceLocked(st.mCurrentTexture,
+                                                    mCurrentTextureImage->graphicBuffer(), fence);
+            if (err != OK) {
+                EGC_LOGE("syncForReleaseLocked: error adding release fence: "
+                         "%s (%d)",
+                         strerror(-err), err);
+                return err;
+            }
+        } else if (st.mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) {
+            EGLSyncKHR fence = mEglSlots[st.mCurrentTexture].mEglFence;
+            if (fence != EGL_NO_SYNC_KHR) {
+                // There is already a fence for the current slot.  We need to
+                // wait on that before replacing it with another fence to
+                // ensure that all outstanding buffer accesses have completed
+                // before the producer accesses it.
+                EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
+                if (result == EGL_FALSE) {
+                    EGC_LOGE("syncForReleaseLocked: error waiting for previous "
+                             "fence: %#x",
+                             eglGetError());
+                    return UNKNOWN_ERROR;
+                } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
+                    EGC_LOGE("syncForReleaseLocked: timeout waiting for previous "
+                             "fence");
+                    return TIMED_OUT;
+                }
+                eglDestroySyncKHR(dpy, fence);
+            }
+
+            // Create a fence for the outstanding accesses in the current
+            // OpenGL ES context.
+            fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
+            if (fence == EGL_NO_SYNC_KHR) {
+                EGC_LOGE("syncForReleaseLocked: error creating fence: %#x", eglGetError());
+                return UNKNOWN_ERROR;
+            }
+            glFlush();
+            mEglSlots[st.mCurrentTexture].mEglFence = fence;
+        }
+    }
+
+    return OK;
+}
+
+status_t EGLConsumer::doGLFenceWaitLocked(SurfaceTexture& st) const {
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLContext ctx = eglGetCurrentContext();
+
+    if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) {
+        EGC_LOGE("doGLFenceWait: invalid current EGLDisplay");
+        return INVALID_OPERATION;
+    }
+
+    if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) {
+        EGC_LOGE("doGLFenceWait: invalid current EGLContext");
+        return INVALID_OPERATION;
+    }
+
+    if (st.mCurrentFence->isValid()) {
+        if (SyncFeatures::getInstance().useWaitSync() &&
+            SyncFeatures::getInstance().useNativeFenceSync()) {
+            // Create an EGLSyncKHR from the current fence.
+            int fenceFd = st.mCurrentFence->dup();
+            if (fenceFd == -1) {
+                EGC_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno);
+                return -errno;
+            }
+            EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE};
+            EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
+            if (sync == EGL_NO_SYNC_KHR) {
+                close(fenceFd);
+                EGC_LOGE("doGLFenceWait: error creating EGL fence: %#x", eglGetError());
+                return UNKNOWN_ERROR;
+            }
+
+            // XXX: The spec draft is inconsistent as to whether this should
+            // return an EGLint or void.  Ignore the return value for now, as
+            // it's not strictly needed.
+            eglWaitSyncKHR(dpy, sync, 0);
+            EGLint eglErr = eglGetError();
+            eglDestroySyncKHR(dpy, sync);
+            if (eglErr != EGL_SUCCESS) {
+                EGC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", eglErr);
+                return UNKNOWN_ERROR;
+            }
+        } else {
+            status_t err = st.mCurrentFence->waitForever("EGLConsumer::doGLFenceWaitLocked");
+            if (err != NO_ERROR) {
+                EGC_LOGE("doGLFenceWait: error waiting for fence: %d", err);
+                return err;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+void EGLConsumer::onFreeBufferLocked(int slotIndex) {
+    mEglSlots[slotIndex].mEglImage.clear();
+}
+
+void EGLConsumer::onAbandonLocked() {
+    mCurrentTextureImage.clear();
+}
+
+EGLConsumer::EglImage::EglImage(sp<GraphicBuffer> graphicBuffer)
+      : mGraphicBuffer(graphicBuffer), mEglImage(EGL_NO_IMAGE_KHR), mEglDisplay(EGL_NO_DISPLAY) {}
+
+EGLConsumer::EglImage::~EglImage() {
+    if (mEglImage != EGL_NO_IMAGE_KHR) {
+        if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
+            ALOGE("~EglImage: eglDestroyImageKHR failed");
+        }
+        eglTerminate(mEglDisplay);
+    }
+}
+
+status_t EGLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, bool forceCreation) {
+    // If there's an image and it's no longer valid, destroy it.
+    bool haveImage = mEglImage != EGL_NO_IMAGE_KHR;
+    bool displayInvalid = mEglDisplay != eglDisplay;
+    if (haveImage && (displayInvalid || forceCreation)) {
+        if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
+            ALOGE("createIfNeeded: eglDestroyImageKHR failed");
+        }
+        eglTerminate(mEglDisplay);
+        mEglImage = EGL_NO_IMAGE_KHR;
+        mEglDisplay = EGL_NO_DISPLAY;
+    }
+
+    // If there's no image, create one.
+    if (mEglImage == EGL_NO_IMAGE_KHR) {
+        mEglDisplay = eglDisplay;
+        mEglImage = createImage(mEglDisplay, mGraphicBuffer);
+    }
+
+    // Fail if we can't create a valid image.
+    if (mEglImage == EGL_NO_IMAGE_KHR) {
+        mEglDisplay = EGL_NO_DISPLAY;
+        const sp<GraphicBuffer>& buffer = mGraphicBuffer;
+        ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d",
+              buffer->getWidth(), buffer->getHeight(), buffer->getStride(), buffer->getUsage(),
+              buffer->getPixelFormat());
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+void EGLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) {
+    glEGLImageTargetTexture2DOES(texTarget, static_cast<GLeglImageOES>(mEglImage));
+}
+
+EGLImageKHR EGLConsumer::EglImage::createImage(EGLDisplay dpy,
+                                               const sp<GraphicBuffer>& graphicBuffer) {
+    EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer());
+    const bool createProtectedImage =
+            (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) && hasEglProtectedContent();
+    EGLint attrs[] = {
+            EGL_IMAGE_PRESERVED_KHR,
+            EGL_TRUE,
+            createProtectedImage ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
+            createProtectedImage ? EGL_TRUE : EGL_NONE,
+            EGL_NONE,
+    };
+    eglInitialize(dpy, nullptr, nullptr);
+    EGLImageKHR image =
+            eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
+    if (image == EGL_NO_IMAGE_KHR) {
+        EGLint error = eglGetError();
+        ALOGE("error creating EGLImage: %#x", error);
+        eglTerminate(dpy);
+    }
+    return image;
+}
+
+} // namespace android
diff --git a/libs/gui/surfacetexture/ImageConsumer.cpp b/libs/gui/surfacetexture/ImageConsumer.cpp
new file mode 100644
index 0000000..4bc4a7b
--- /dev/null
+++ b/libs/gui/surfacetexture/ImageConsumer.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <gui/BufferQueue.h>
+#include <gui/surfacetexture/ImageConsumer.h>
+#include <gui/surfacetexture/SurfaceTexture.h>
+
+// Macro for including the SurfaceTexture name in log messages
+#define IMG_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__)
+
+namespace android {
+
+void ImageConsumer::onReleaseBufferLocked(int buf) {
+    mImageSlots[buf].eglFence() = EGL_NO_SYNC_KHR;
+}
+
+sp<GraphicBuffer> ImageConsumer::dequeueBuffer(int* outSlotid, android_dataspace* outDataspace,
+                                               bool* outQueueEmpty, SurfaceTexture& st,
+                                               SurfaceTexture_createReleaseFence createFence,
+                                               SurfaceTexture_fenceWait fenceWait,
+                                               void* fencePassThroughHandle) {
+    BufferItem item;
+    status_t err;
+    err = st.acquireBufferLocked(&item, 0);
+    if (err != OK) {
+        if (err != BufferQueue::NO_BUFFER_AVAILABLE) {
+            IMG_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
+        } else {
+            int slot = st.mCurrentTexture;
+            if (slot != BufferItem::INVALID_BUFFER_SLOT) {
+                *outQueueEmpty = true;
+                *outDataspace = st.mCurrentDataSpace;
+                *outSlotid = slot;
+                return st.mSlots[slot].mGraphicBuffer;
+            }
+        }
+        return nullptr;
+    }
+
+    int slot = item.mSlot;
+    if (item.mFence->isValid()) {
+        // Wait on the producer fence for the buffer to be ready.
+        err = fenceWait(item.mFence->get(), fencePassThroughHandle);
+        if (err != OK) {
+            st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, EGL_NO_DISPLAY,
+                                   EGL_NO_SYNC_KHR);
+            return nullptr;
+        }
+    }
+
+    // Release old buffer.
+    if (st.mCurrentTexture != BufferItem::INVALID_BUFFER_SLOT) {
+        // If needed, set the released slot's fence to guard against a producer
+        // accessing the buffer before the outstanding accesses have completed.
+        int releaseFenceId = -1;
+        EGLDisplay display = EGL_NO_DISPLAY;
+        err = createFence(st.mUseFenceSync, &mImageSlots[slot].eglFence(), &display,
+                          &releaseFenceId, fencePassThroughHandle);
+        if (OK != err) {
+            st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, EGL_NO_DISPLAY,
+                                   EGL_NO_SYNC_KHR);
+            return nullptr;
+        }
+
+        if (releaseFenceId != -1) {
+            sp<Fence> releaseFence(new Fence(releaseFenceId));
+            status_t err = st.addReleaseFenceLocked(st.mCurrentTexture,
+                                                    st.mSlots[st.mCurrentTexture].mGraphicBuffer,
+                                                    releaseFence);
+            if (err != OK) {
+                IMG_LOGE("dequeueImage: error adding release fence: %s (%d)", strerror(-err), err);
+                st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, EGL_NO_DISPLAY,
+                                       EGL_NO_SYNC_KHR);
+                return nullptr;
+            }
+        }
+
+        // Finally release the old buffer.
+        status_t status =
+                st.releaseBufferLocked(st.mCurrentTexture,
+                                       st.mSlots[st.mCurrentTexture].mGraphicBuffer, display,
+                                       mImageSlots[st.mCurrentTexture].eglFence());
+        if (status < NO_ERROR) {
+            IMG_LOGE("dequeueImage: failed to release buffer: %s (%d)", strerror(-status), status);
+            err = status;
+            // Keep going, with error raised.
+        }
+    }
+
+    // Update the state.
+    st.mCurrentTexture = slot;
+    st.mCurrentCrop = item.mCrop;
+    st.mCurrentTransform = item.mTransform;
+    st.mCurrentScalingMode = item.mScalingMode;
+    st.mCurrentTimestamp = item.mTimestamp;
+    st.mCurrentDataSpace = item.mDataSpace;
+    st.mCurrentFence = item.mFence;
+    st.mCurrentFenceTime = item.mFenceTime;
+    st.mCurrentFrameNumber = item.mFrameNumber;
+    st.computeCurrentTransformMatrixLocked();
+
+    *outQueueEmpty = false;
+    *outDataspace = item.mDataSpace;
+    *outSlotid = slot;
+    return st.mSlots[slot].mGraphicBuffer;
+}
+
+} /* namespace android */
diff --git a/libs/gui/surfacetexture/SurfaceTexture.cpp b/libs/gui/surfacetexture/SurfaceTexture.cpp
new file mode 100644
index 0000000..25e5618
--- /dev/null
+++ b/libs/gui/surfacetexture/SurfaceTexture.cpp
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <cutils/compiler.h>
+#include <gui/BufferQueue.h>
+#include <gui/surfacetexture/ImageConsumer.h>
+#include <gui/surfacetexture/SurfaceTexture.h>
+#include <gui/surfacetexture/surface_texture_platform.h>
+#include <math/mat4.h>
+#include <system/window.h>
+#include <utils/Trace.h>
+
+namespace android {
+
+// Macros for including the SurfaceTexture name in log messages
+#define SFT_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define SFT_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define SFT_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define SFT_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
+
+static const mat4 mtxIdentity;
+
+SurfaceTexture::SurfaceTexture(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
+                               uint32_t texTarget, bool useFenceSync, bool isControlledByApp)
+      : ConsumerBase(bq, isControlledByApp),
+        mCurrentCrop(Rect::EMPTY_RECT),
+        mCurrentTransform(0),
+        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+        mCurrentFence(Fence::NO_FENCE),
+        mCurrentTimestamp(0),
+        mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
+        mCurrentFrameNumber(0),
+        mDefaultWidth(1),
+        mDefaultHeight(1),
+        mFilteringEnabled(true),
+        mTexName(tex),
+        mUseFenceSync(useFenceSync),
+        mTexTarget(texTarget),
+        mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
+        mOpMode(OpMode::attachedToGL) {
+    SFT_LOGV("SurfaceTexture");
+
+    memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix));
+
+    mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
+}
+
+SurfaceTexture::SurfaceTexture(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
+                               bool useFenceSync, bool isControlledByApp)
+      : ConsumerBase(bq, isControlledByApp),
+        mCurrentCrop(Rect::EMPTY_RECT),
+        mCurrentTransform(0),
+        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+        mCurrentFence(Fence::NO_FENCE),
+        mCurrentTimestamp(0),
+        mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
+        mCurrentFrameNumber(0),
+        mDefaultWidth(1),
+        mDefaultHeight(1),
+        mFilteringEnabled(true),
+        mTexName(0),
+        mUseFenceSync(useFenceSync),
+        mTexTarget(texTarget),
+        mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
+        mOpMode(OpMode::detached) {
+    SFT_LOGV("SurfaceTexture");
+
+    memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix));
+
+    mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
+}
+
+status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) {
+    Mutex::Autolock lock(mMutex);
+    if (mAbandoned) {
+        SFT_LOGE("setDefaultBufferSize: SurfaceTexture is abandoned!");
+        return NO_INIT;
+    }
+    mDefaultWidth = w;
+    mDefaultHeight = h;
+    return mConsumer->setDefaultBufferSize(w, h);
+}
+
+status_t SurfaceTexture::updateTexImage() {
+    ATRACE_CALL();
+    SFT_LOGV("updateTexImage");
+    Mutex::Autolock lock(mMutex);
+
+    if (mAbandoned) {
+        SFT_LOGE("updateTexImage: SurfaceTexture is abandoned!");
+        return NO_INIT;
+    }
+
+    return mEGLConsumer.updateTexImage(*this);
+}
+
+status_t SurfaceTexture::releaseTexImage() {
+    // releaseTexImage can be invoked even when not attached to a GL context.
+    ATRACE_CALL();
+    SFT_LOGV("releaseTexImage");
+    Mutex::Autolock lock(mMutex);
+
+    if (mAbandoned) {
+        SFT_LOGE("releaseTexImage: SurfaceTexture is abandoned!");
+        return NO_INIT;
+    }
+
+    return mEGLConsumer.releaseTexImage(*this);
+}
+
+status_t SurfaceTexture::acquireBufferLocked(BufferItem* item, nsecs_t presentWhen,
+                                             uint64_t maxFrameNumber) {
+    status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen, maxFrameNumber);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    switch (mOpMode) {
+        case OpMode::attachedToConsumer:
+            break;
+        case OpMode::attachedToGL:
+            mEGLConsumer.onAcquireBufferLocked(item, *this);
+            break;
+        case OpMode::detached:
+            break;
+    }
+
+    return NO_ERROR;
+}
+
+status_t SurfaceTexture::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer,
+                                             EGLDisplay display, EGLSyncKHR eglFence) {
+    // release the buffer if it hasn't already been discarded by the
+    // BufferQueue. This can happen, for example, when the producer of this
+    // buffer has reallocated the original buffer slot after this buffer
+    // was acquired.
+    status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence);
+    // We could be releasing an EGL/Vulkan buffer, even if not currently
+    // attached to a GL context.
+    mImageConsumer.onReleaseBufferLocked(buf);
+    mEGLConsumer.onReleaseBufferLocked(buf);
+    return err;
+}
+
+status_t SurfaceTexture::detachFromContext() {
+    ATRACE_CALL();
+    SFT_LOGV("detachFromContext");
+    Mutex::Autolock lock(mMutex);
+
+    if (mAbandoned) {
+        SFT_LOGE("detachFromContext: abandoned SurfaceTexture");
+        return NO_INIT;
+    }
+
+    if (mOpMode != OpMode::attachedToGL) {
+        SFT_LOGE("detachFromContext: SurfaceTexture is not attached to a GL context");
+        return INVALID_OPERATION;
+    }
+
+    status_t err = mEGLConsumer.detachFromContext(*this);
+    if (err == OK) {
+        mOpMode = OpMode::detached;
+    }
+
+    return err;
+}
+
+status_t SurfaceTexture::attachToContext(uint32_t tex) {
+    ATRACE_CALL();
+    SFT_LOGV("attachToContext");
+    Mutex::Autolock lock(mMutex);
+
+    if (mAbandoned) {
+        SFT_LOGE("attachToContext: abandoned SurfaceTexture");
+        return NO_INIT;
+    }
+
+    if (mOpMode != OpMode::detached) {
+        SFT_LOGE("attachToContext: SurfaceTexture is already attached to a "
+                 "context");
+        return INVALID_OPERATION;
+    }
+
+    return mEGLConsumer.attachToContext(tex, *this);
+}
+
+void SurfaceTexture::takeConsumerOwnership() {
+    ATRACE_CALL();
+    Mutex::Autolock _l(mMutex);
+    if (mAbandoned) {
+        SFT_LOGE("attachToView: abandoned SurfaceTexture");
+        return;
+    }
+    if (mOpMode == OpMode::detached) {
+        mOpMode = OpMode::attachedToConsumer;
+
+        if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
+            // release possible EGLConsumer texture cache
+            mEGLConsumer.onFreeBufferLocked(mCurrentTexture);
+            mEGLConsumer.onAbandonLocked();
+        }
+    } else {
+        SFT_LOGE("attachToView: already attached");
+    }
+}
+
+void SurfaceTexture::releaseConsumerOwnership() {
+    ATRACE_CALL();
+    Mutex::Autolock _l(mMutex);
+
+    if (mAbandoned) {
+        SFT_LOGE("detachFromView: abandoned SurfaceTexture");
+        return;
+    }
+
+    if (mOpMode == OpMode::attachedToConsumer) {
+        mOpMode = OpMode::detached;
+    } else {
+        SFT_LOGE("detachFromView: not attached to View");
+    }
+}
+
+uint32_t SurfaceTexture::getCurrentTextureTarget() const {
+    return mTexTarget;
+}
+
+void SurfaceTexture::getTransformMatrix(float mtx[16]) {
+    Mutex::Autolock lock(mMutex);
+    memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
+}
+
+void SurfaceTexture::setFilteringEnabled(bool enabled) {
+    Mutex::Autolock lock(mMutex);
+    if (mAbandoned) {
+        SFT_LOGE("setFilteringEnabled: SurfaceTexture is abandoned!");
+        return;
+    }
+    bool needsRecompute = mFilteringEnabled != enabled;
+    mFilteringEnabled = enabled;
+
+    if (needsRecompute && mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) {
+        SFT_LOGD("setFilteringEnabled called with no current item");
+    }
+
+    if (needsRecompute && mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
+        computeCurrentTransformMatrixLocked();
+    }
+}
+
+void SurfaceTexture::computeCurrentTransformMatrixLocked() {
+    SFT_LOGV("computeCurrentTransformMatrixLocked");
+    sp<GraphicBuffer> buf = (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT)
+            ? nullptr
+            : mSlots[mCurrentTexture].mGraphicBuffer;
+    if (buf == nullptr) {
+        SFT_LOGD("computeCurrentTransformMatrixLocked: no current item");
+    }
+    computeTransformMatrix(mCurrentTransformMatrix, buf, mCurrentCrop, mCurrentTransform,
+                           mFilteringEnabled);
+}
+
+void SurfaceTexture::computeTransformMatrix(float outTransform[16], const sp<GraphicBuffer>& buf,
+                                            const Rect& cropRect, uint32_t transform,
+                                            bool filtering) {
+    // Transform matrices
+    static const mat4 mtxFlipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
+    static const mat4 mtxFlipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
+    static const mat4 mtxRot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
+
+    mat4 xform;
+    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+        xform *= mtxFlipH;
+    }
+    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+        xform *= mtxFlipV;
+    }
+    if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+        xform *= mtxRot90;
+    }
+
+    if (!cropRect.isEmpty() && buf.get()) {
+        float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f;
+        float bufferWidth = buf->getWidth();
+        float bufferHeight = buf->getHeight();
+        float shrinkAmount = 0.0f;
+        if (filtering) {
+            // In order to prevent bilinear sampling beyond the edge of the
+            // crop rectangle we may need to shrink it by 2 texels in each
+            // dimension.  Normally this would just need to take 1/2 a texel
+            // off each end, but because the chroma channels of YUV420 images
+            // are subsampled we may need to shrink the crop region by a whole
+            // texel on each side.
+            switch (buf->getPixelFormat()) {
+                case PIXEL_FORMAT_RGBA_8888:
+                case PIXEL_FORMAT_RGBX_8888:
+                case PIXEL_FORMAT_RGBA_FP16:
+                case PIXEL_FORMAT_RGBA_1010102:
+                case PIXEL_FORMAT_RGB_888:
+                case PIXEL_FORMAT_RGB_565:
+                case PIXEL_FORMAT_BGRA_8888:
+                    // We know there's no subsampling of any channels, so we
+                    // only need to shrink by a half a pixel.
+                    shrinkAmount = 0.5;
+                    break;
+
+                default:
+                    // If we don't recognize the format, we must assume the
+                    // worst case (that we care about), which is YUV420.
+                    shrinkAmount = 1.0;
+                    break;
+            }
+        }
+
+        // Only shrink the dimensions that are not the size of the buffer.
+        if (cropRect.width() < bufferWidth) {
+            tx = (float(cropRect.left) + shrinkAmount) / bufferWidth;
+            sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / bufferWidth;
+        }
+        if (cropRect.height() < bufferHeight) {
+            ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / bufferHeight;
+            sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / bufferHeight;
+        }
+
+        mat4 crop(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1);
+        xform = crop * xform;
+    }
+
+    // SurfaceFlinger expects the top of its window textures to be at a Y
+    // coordinate of 0, so SurfaceTexture must behave the same way.  We don't
+    // want to expose this to applications, however, so we must add an
+    // additional vertical flip to the transform after all the other transforms.
+    xform = mtxFlipV * xform;
+
+    memcpy(outTransform, xform.asArray(), sizeof(xform));
+}
+
+Rect SurfaceTexture::scaleDownCrop(const Rect& crop, uint32_t bufferWidth, uint32_t bufferHeight) {
+    Rect outCrop = crop;
+
+    uint32_t newWidth = static_cast<uint32_t>(crop.width());
+    uint32_t newHeight = static_cast<uint32_t>(crop.height());
+
+    if (newWidth * bufferHeight > newHeight * bufferWidth) {
+        newWidth = newHeight * bufferWidth / bufferHeight;
+        ALOGV("too wide: newWidth = %d", newWidth);
+    } else if (newWidth * bufferHeight < newHeight * bufferWidth) {
+        newHeight = newWidth * bufferHeight / bufferWidth;
+        ALOGV("too tall: newHeight = %d", newHeight);
+    }
+
+    uint32_t currentWidth = static_cast<uint32_t>(crop.width());
+    uint32_t currentHeight = static_cast<uint32_t>(crop.height());
+
+    // The crop is too wide
+    if (newWidth < currentWidth) {
+        uint32_t dw = currentWidth - newWidth;
+        auto halfdw = dw / 2;
+        outCrop.left += halfdw;
+        // Not halfdw because it would subtract 1 too few when dw is odd
+        outCrop.right -= (dw - halfdw);
+        // The crop is too tall
+    } else if (newHeight < currentHeight) {
+        uint32_t dh = currentHeight - newHeight;
+        auto halfdh = dh / 2;
+        outCrop.top += halfdh;
+        // Not halfdh because it would subtract 1 too few when dh is odd
+        outCrop.bottom -= (dh - halfdh);
+    }
+
+    ALOGV("getCurrentCrop final crop [%d,%d,%d,%d]", outCrop.left, outCrop.top, outCrop.right,
+          outCrop.bottom);
+
+    return outCrop;
+}
+
+nsecs_t SurfaceTexture::getTimestamp() {
+    SFT_LOGV("getTimestamp");
+    Mutex::Autolock lock(mMutex);
+    return mCurrentTimestamp;
+}
+
+android_dataspace SurfaceTexture::getCurrentDataSpace() {
+    SFT_LOGV("getCurrentDataSpace");
+    Mutex::Autolock lock(mMutex);
+    return mCurrentDataSpace;
+}
+
+uint64_t SurfaceTexture::getFrameNumber() {
+    SFT_LOGV("getFrameNumber");
+    Mutex::Autolock lock(mMutex);
+    return mCurrentFrameNumber;
+}
+
+Rect SurfaceTexture::getCurrentCrop() const {
+    Mutex::Autolock lock(mMutex);
+    return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)
+            ? scaleDownCrop(mCurrentCrop, mDefaultWidth, mDefaultHeight)
+            : mCurrentCrop;
+}
+
+uint32_t SurfaceTexture::getCurrentTransform() const {
+    Mutex::Autolock lock(mMutex);
+    return mCurrentTransform;
+}
+
+uint32_t SurfaceTexture::getCurrentScalingMode() const {
+    Mutex::Autolock lock(mMutex);
+    return mCurrentScalingMode;
+}
+
+sp<Fence> SurfaceTexture::getCurrentFence() const {
+    Mutex::Autolock lock(mMutex);
+    return mCurrentFence;
+}
+
+std::shared_ptr<FenceTime> SurfaceTexture::getCurrentFenceTime() const {
+    Mutex::Autolock lock(mMutex);
+    return mCurrentFenceTime;
+}
+
+void SurfaceTexture::freeBufferLocked(int slotIndex) {
+    SFT_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
+    if (slotIndex == mCurrentTexture) {
+        mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
+    }
+    // The slotIndex buffer could have EGL cache, but there is no way to tell
+    // for sure. Buffers can be freed after SurfaceTexture has detached from GL
+    // context or View.
+    mEGLConsumer.onFreeBufferLocked(slotIndex);
+    ConsumerBase::freeBufferLocked(slotIndex);
+}
+
+void SurfaceTexture::abandonLocked() {
+    SFT_LOGV("abandonLocked");
+    mEGLConsumer.onAbandonLocked();
+    ConsumerBase::abandonLocked();
+}
+
+status_t SurfaceTexture::setConsumerUsageBits(uint64_t usage) {
+    return ConsumerBase::setConsumerUsageBits(usage | DEFAULT_USAGE_FLAGS);
+}
+
+void SurfaceTexture::dumpLocked(String8& result, const char* prefix) const {
+    result.appendFormat("%smTexName=%d mCurrentTexture=%d\n"
+                        "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n",
+                        prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left,
+                        mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
+                        mCurrentTransform);
+
+    ConsumerBase::dumpLocked(result, prefix);
+}
+
+sp<GraphicBuffer> SurfaceTexture::dequeueBuffer(int* outSlotid, android_dataspace* outDataspace,
+                                                float* outTransformMatrix, bool* outQueueEmpty,
+                                                SurfaceTexture_createReleaseFence createFence,
+                                                SurfaceTexture_fenceWait fenceWait,
+                                                void* fencePassThroughHandle) {
+    Mutex::Autolock _l(mMutex);
+    sp<GraphicBuffer> buffer;
+
+    if (mAbandoned) {
+        SFT_LOGE("dequeueImage: SurfaceTexture is abandoned!");
+        return buffer;
+    }
+
+    if (mOpMode != OpMode::attachedToConsumer) {
+        SFT_LOGE("dequeueImage: SurfaceTexture is not attached to a View");
+        return buffer;
+    }
+
+    buffer = mImageConsumer.dequeueBuffer(outSlotid, outDataspace, outQueueEmpty, *this,
+                                          createFence, fenceWait, fencePassThroughHandle);
+    memcpy(outTransformMatrix, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
+    return buffer;
+}
+
+unsigned int ASurfaceTexture_getCurrentTextureTarget(ASurfaceTexture* st) {
+    return st->consumer->getCurrentTextureTarget();
+}
+
+void ASurfaceTexture_takeConsumerOwnership(ASurfaceTexture* texture) {
+    texture->consumer->takeConsumerOwnership();
+}
+
+void ASurfaceTexture_releaseConsumerOwnership(ASurfaceTexture* texture) {
+    texture->consumer->releaseConsumerOwnership();
+}
+
+AHardwareBuffer* ASurfaceTexture_dequeueBuffer(ASurfaceTexture* st, int* outSlotid,
+                                               android_dataspace* outDataspace,
+                                               float* outTransformMatrix, bool* outNewContent,
+                                               ASurfaceTexture_createReleaseFence createFence,
+                                               ASurfaceTexture_fenceWait fenceWait, void* handle) {
+    sp<GraphicBuffer> buffer;
+    *outNewContent = false;
+    bool queueEmpty;
+    do {
+        buffer = st->consumer->dequeueBuffer(outSlotid, outDataspace, outTransformMatrix,
+                                             &queueEmpty, createFence, fenceWait, handle);
+        if (!queueEmpty) {
+            *outNewContent = true;
+        }
+    } while (buffer.get() && (!queueEmpty));
+    return reinterpret_cast<AHardwareBuffer*>(buffer.get());
+}
+
+ASurfaceTexture* ASurfaceTexture_create(sp<SurfaceTexture> consumer,
+                                        sp<IGraphicBufferProducer> producer) {
+    ASurfaceTexture* ast = new ASurfaceTexture;
+    ast->consumer = consumer;
+    ast->producer = producer;
+    return ast;
+}
+
+} // namespace android
