diff options
author | Stan Iliev <stani@google.com> | 2018-08-30 18:56:41 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 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() { |