Reland "TextureView Vulkan support and optimized OpenGL draw"

Fix an issue with incorrect texture matrix, when there is 90/270 rotation.
This happened, because after refactoring SkImage has buffer width/height,
instead of layer width/height.
This reverts commit a683eb3945320f592f58705c3c31b3c044f4bd72.

Bug: 113673613
Test: Ran TextureView CTS and lensblur in camera app
Change-Id: If3bcf9cd5195de09fd67a753708568a8e3ca3a9a
diff --git a/libs/hwui/surfacetexture/ImageConsumer.cpp b/libs/hwui/surfacetexture/ImageConsumer.cpp
new file mode 100644
index 0000000..9ffccfb
--- /dev/null
+++ b/libs/hwui/surfacetexture/ImageConsumer.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+#include "ImageConsumer.h"
+#include <gui/BufferQueue.h>
+#include "Properties.h"
+#include "SurfaceTexture.h"
+#include "renderstate/RenderState.h"
+#include "renderthread/EglManager.h"
+#include "renderthread/RenderThread.h"
+#include "renderthread/VulkanManager.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::onFreeBufferLocked(int slotIndex) {
+    mImageSlots[slotIndex].mImage.reset();
+}
+
+void ImageConsumer::onAcquireBufferLocked(BufferItem* item) {
+    // If item->mGraphicBuffer is not null, this buffer has not been acquired
+    // before, so any prior SkImage is created with a stale buffer. This resets the stale SkImage.
+    if (item->mGraphicBuffer != nullptr) {
+        mImageSlots[item->mSlot].mImage.reset();
+    }
+}
+
+void ImageConsumer::onReleaseBufferLocked(int buf) {
+    mImageSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
+}
+
+void ImageConsumer::ImageSlot::createIfNeeded(sp<GraphicBuffer> graphicBuffer) {
+    if (!mImage.get()) {
+        mImage = graphicBuffer.get()
+                         ? SkImage::MakeFromAHardwareBuffer(
+                                   reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()),
+                                   kPremul_SkAlphaType)
+                         : nullptr;
+    }
+}
+
+sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st,
+                                           uirenderer::RenderState& renderState) {
+    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) {
+                *queueEmpty = true;
+                mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer);
+                return mImageSlots[slot].mImage;
+            }
+        }
+        return nullptr;
+    }
+
+    int slot = item.mSlot;
+    if (item.mFence->isValid()) {
+        // Wait on the producer fence for the buffer to be ready.
+        if (uirenderer::Properties::getRenderPipelineType() ==
+            uirenderer::RenderPipelineType::SkiaGL) {
+            err = renderState.getRenderThread().eglManager().fenceWait(item.mFence);
+        } else {
+            err = renderState.getRenderThread().vulkanManager().fenceWait(item.mFence);
+        }
+        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.
+        sp<Fence> releaseFence;
+        EGLDisplay display = EGL_NO_DISPLAY;
+        if (uirenderer::Properties::getRenderPipelineType() ==
+            uirenderer::RenderPipelineType::SkiaGL) {
+            auto& eglManager = renderState.getRenderThread().eglManager();
+            display = eglManager.eglDisplay();
+            err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].mEglFence,
+                                                releaseFence);
+        } else {
+            err = renderState.getRenderThread().vulkanManager().createReleaseFence(releaseFence);
+        }
+        if (OK != err) {
+            st.releaseBufferLocked(slot, st.mSlots[slot].mGraphicBuffer, EGL_NO_DISPLAY,
+                                   EGL_NO_SYNC_KHR);
+            return nullptr;
+        }
+
+        if (releaseFence.get()) {
+            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].mEglFence);
+        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();
+
+    *queueEmpty = false;
+    mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer);
+    return mImageSlots[slot].mImage;
+}
+
+} /* namespace android */