summaryrefslogtreecommitdiff
path: root/libs/hwui/DeferredLayerUpdater.cpp
diff options
context:
space:
mode:
authorStan Iliev <stani@google.com>2018-08-30 18:56:41 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-08-30 18:56:41 +0000
commite6cfb09cc4938078d14b1b4abca1678ac8fb170c (patch)
treec71f82bc74a53be28d30c88ca3b8f84b666578de /libs/hwui/DeferredLayerUpdater.cpp
parentc72888de5dec8327da3d1a8d328f2c92a629d91e (diff)
parent867c43de0544217d26c3ee18f4d6603bb2ea97ce (diff)
Merge "Revert "TextureView Vulkan support and optimized OpenGL draw""
Diffstat (limited to 'libs/hwui/DeferredLayerUpdater.cpp')
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp123
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() {