diff options
| author | 2018-08-30 18:56:41 +0000 | |
|---|---|---|
| committer | 2018-08-30 18:56:41 +0000 | |
| commit | e6cfb09cc4938078d14b1b4abca1678ac8fb170c (patch) | |
| tree | c71f82bc74a53be28d30c88ca3b8f84b666578de /libs/hwui/DeferredLayerUpdater.cpp | |
| parent | c72888de5dec8327da3d1a8d328f2c92a629d91e (diff) | |
| parent | 867c43de0544217d26c3ee18f4d6603bb2ea97ce (diff) | |
Merge "Revert "TextureView Vulkan support and optimized OpenGL draw""
Diffstat (limited to 'libs/hwui/DeferredLayerUpdater.cpp')
| -rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 123 | 
1 files changed, 90 insertions, 33 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 00916559a9c2..569de76f294e 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -15,20 +15,27 @@   */  #include "DeferredLayerUpdater.h" +#include "GlLayer.h" +#include "VkLayer.h"  #include "renderstate/RenderState.h" +#include "renderthread/EglManager.h" +#include "renderthread/RenderTask.h"  #include "utils/PaintUtils.h"  namespace android {  namespace uirenderer { -DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState) +DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState, CreateLayerFn createLayerFn, +                                           Layer::Api layerApi)          : mRenderState(renderState)          , mBlend(false)          , mSurfaceTexture(nullptr)          , mTransform(nullptr)          , mGLContextAttached(false)          , mUpdateTexImage(false) -        , mLayer(nullptr) { +        , mLayer(nullptr) +        , mLayerApi(layerApi) +        , mCreateLayerFn(createLayerFn) {      renderState.registerDeferredLayerUpdater(this);  } @@ -43,9 +50,13 @@ void DeferredLayerUpdater::destroyLayer() {          return;      } -    if (mSurfaceTexture.get() && mGLContextAttached) { -        mSurfaceTexture->detachFromView(); +    if (mSurfaceTexture.get() && mLayerApi == Layer::Api::OpenGL && mGLContextAttached) { +        status_t err = mSurfaceTexture->detachFromContext();          mGLContextAttached = false; +        if (err != 0) { +            // TODO: Elevate to fatal exception +            ALOGE("Failed to detach SurfaceTexture from context %d", err); +        }      }      mLayer->postDecStrong(); @@ -64,53 +75,99 @@ void DeferredLayerUpdater::setPaint(const SkPaint* paint) {  void DeferredLayerUpdater::apply() {      if (!mLayer) { -        mLayer = new Layer(mRenderState, mColorFilter, mAlpha, mMode); +        mLayer = mCreateLayerFn(mRenderState, mWidth, mHeight, mColorFilter, mAlpha, mMode, mBlend);      }      mLayer->setColorFilter(mColorFilter);      mLayer->setAlpha(mAlpha, mMode);      if (mSurfaceTexture.get()) { -        if (!mGLContextAttached) { -            mGLContextAttached = true; -            mUpdateTexImage = true; -            mSurfaceTexture->attachToView(); -        } -        if (mUpdateTexImage) { -            mUpdateTexImage = false; -            sk_sp<SkImage> layerImage; -            SkMatrix textureTransform; -            android_dataspace dataSpace; -            bool queueEmpty = true; -            // If the SurfaceTexture queue is in synchronous mode, need to discard all -            // but latest frame. Since we can't tell which mode it is in, -            // do this unconditionally. -            do { -                layerImage = mSurfaceTexture->dequeueImage(textureTransform, dataSpace, &queueEmpty, -                        mRenderState); -            } while (layerImage.get() && (!queueEmpty)); -            if (layerImage.get()) { -                // force filtration if buffer size != layer size -                bool forceFilter = mWidth != layerImage->width() || mHeight != layerImage->height(); -                updateLayer(forceFilter, textureTransform, dataSpace, layerImage); +        if (mLayer->getApi() == Layer::Api::Vulkan) { +            if (mUpdateTexImage) { +                mUpdateTexImage = false; +                doUpdateVkTexImage(); +            } +        } else { +            LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL, +                                "apply surfaceTexture with non GL backend %x, GL %x, VK %x", +                                mLayer->getApi(), Layer::Api::OpenGL, Layer::Api::Vulkan); +            if (!mGLContextAttached) { +                mGLContextAttached = true; +                mUpdateTexImage = true; +                mSurfaceTexture->attachToContext(static_cast<GlLayer*>(mLayer)->getTextureId());              } +            if (mUpdateTexImage) { +                mUpdateTexImage = false; +                doUpdateTexImage(); +            } +            GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget(); +            static_cast<GlLayer*>(mLayer)->setRenderTarget(renderTarget);          } -          if (mTransform) { -            mLayer->getTransform() = *mTransform; +            mLayer->getTransform().load(*mTransform);              setTransform(nullptr);          }      }  } -void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform, -        android_dataspace dataspace, const sk_sp<SkImage>& layerImage) { +void DeferredLayerUpdater::doUpdateTexImage() { +    LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::OpenGL, +                        "doUpdateTexImage non GL backend %x, GL %x, VK %x", mLayer->getApi(), +                        Layer::Api::OpenGL, Layer::Api::Vulkan); +    if (mSurfaceTexture->updateTexImage() == NO_ERROR) { +        float transform[16]; + +        int64_t frameNumber = mSurfaceTexture->getFrameNumber(); +        // If the GLConsumer queue is in synchronous mode, need to discard all +        // but latest frame, using the frame number to tell when we no longer +        // have newer frames to target. Since we can't tell which mode it is in, +        // do this unconditionally. +        int dropCounter = 0; +        while (mSurfaceTexture->updateTexImage() == NO_ERROR) { +            int64_t newFrameNumber = mSurfaceTexture->getFrameNumber(); +            if (newFrameNumber == frameNumber) break; +            frameNumber = newFrameNumber; +            dropCounter++; +        } + +        bool forceFilter = false; +        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer(); +        if (buffer != nullptr) { +            // force filtration if buffer size != layer size +            forceFilter = mWidth != static_cast<int>(buffer->getWidth()) || +                          mHeight != static_cast<int>(buffer->getHeight()); +        } + +#if DEBUG_RENDERER +        if (dropCounter > 0) { +            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter); +        } +#endif +        mSurfaceTexture->getTransformMatrix(transform); + +        updateLayer(forceFilter, transform, mSurfaceTexture->getCurrentDataSpace()); +    } +} + +void DeferredLayerUpdater::doUpdateVkTexImage() { +    LOG_ALWAYS_FATAL_IF(mLayer->getApi() != Layer::Api::Vulkan, +                        "updateLayer non Vulkan backend %x, GL %x, VK %x", mLayer->getApi(), +                        Layer::Api::OpenGL, Layer::Api::Vulkan); + +    static const mat4 identityMatrix; +    updateLayer(false, identityMatrix.data, HAL_DATASPACE_UNKNOWN); + +    VkLayer* vkLayer = static_cast<VkLayer*>(mLayer); +    vkLayer->updateTexture(); +} + +void DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform, +                                       android_dataspace dataspace) {      mLayer->setBlend(mBlend);      mLayer->setForceFilter(forceFilter);      mLayer->setSize(mWidth, mHeight); -    mLayer->getTexTransform() = textureTransform; +    mLayer->getTexTransform().load(textureTransform);      mLayer->setDataSpace(dataspace); -    mLayer->setImage(layerImage);  }  void DeferredLayerUpdater::detachSurfaceTexture() {  |