TextureView Vulkan support and optimized OpenGL draw
Render TextureView as hardware bitmaps, instead of GL textures.
Cache SkImage for each observed GraphicBuffer, which is faster
even for GL.
Implement C++ SurfaceTexture, which allows Java SurfaceTexture
to be used with Vulkan HWUI render thread and application GL.
threads. Delete GLLayer and VkLayer classes and texture code
from old HWUI pipeline.
Test: Ran skiagl and skiavk pipeline with a TextureView app.
Test: TextureView CTS tests pass for GL pipeline.
Test: Ran Android NDK Native codec sample app.
Change-Id: Idc94f864ce2d34fd6ceff4be4fc7d3327e99879c
diff --git a/libs/hwui/renderstate/PixelBufferState.cpp b/libs/hwui/renderstate/PixelBufferState.cpp
deleted file mode 100644
index 3a6efb8..0000000
--- a/libs/hwui/renderstate/PixelBufferState.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 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 "renderstate/PixelBufferState.h"
-
-namespace android {
-namespace uirenderer {
-
-PixelBufferState::PixelBufferState() : mCurrentPixelBuffer(0) {}
-
-bool PixelBufferState::bind(GLuint buffer) {
- if (mCurrentPixelBuffer != buffer) {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
- mCurrentPixelBuffer = buffer;
- return true;
- }
- return false;
-}
-
-bool PixelBufferState::unbind() {
- if (mCurrentPixelBuffer) {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- mCurrentPixelBuffer = 0;
- return true;
- }
- return false;
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderstate/PixelBufferState.h b/libs/hwui/renderstate/PixelBufferState.h
deleted file mode 100644
index f7ae6c5..0000000
--- a/libs/hwui/renderstate/PixelBufferState.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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 RENDERSTATE_PIXELBUFFERSTATE_H
-#define RENDERSTATE_PIXELBUFFERSTATE_H
-
-#include <GLES3/gl3.h>
-
-namespace android {
-namespace uirenderer {
-
-class PixelBufferState {
- friend class Caches; // TODO: move to RenderState
-public:
- bool bind(GLuint buffer);
- bool unbind();
-
-private:
- PixelBufferState();
- GLuint mCurrentPixelBuffer;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif // RENDERSTATE_PIXELBUFFERSTATE_H
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 3be84f58..b524bcb 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -16,8 +16,6 @@
#include "renderstate/RenderState.h"
#include <GpuMemoryTracker.h>
#include "DeferredLayerUpdater.h"
-#include "GlLayer.h"
-#include "VkLayer.h"
#include "Snapshot.h"
#include "renderthread/CanvasContext.h"
@@ -39,44 +37,11 @@
RenderState::~RenderState() {
}
-void RenderState::onGLContextCreated() {
- GpuMemoryTracker::onGpuContextCreated();
-
- // This is delayed because the first access of Caches makes GL calls
- if (!mCaches) {
- mCaches = &Caches::createInstance(*this);
- }
- mCaches->init();
-}
-
-static void layerLostGlContext(Layer* layer) {
- LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL,
- "layerLostGlContext on non GL layer");
- static_cast<GlLayer*>(layer)->onGlContextLost();
-}
-
-void RenderState::onGLContextDestroyed() {
- // TODO: reset all cached state in state objects
- std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext);
-
- mCaches->terminate();
-
- destroyLayersInUpdater();
- GpuMemoryTracker::onGpuContextDestroyed();
-}
-
-void RenderState::onVkContextCreated() {
+void RenderState::onContextCreated() {
GpuMemoryTracker::onGpuContextCreated();
}
-static void layerDestroyedVkContext(Layer* layer) {
- LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::Vulkan,
- "layerLostVkContext on non Vulkan layer");
- static_cast<VkLayer*>(layer)->onVkContextDestroyed();
-}
-
-void RenderState::onVkContextDestroyed() {
- std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext);
+void RenderState::onContextDestroyed() {
destroyLayersInUpdater();
GpuMemoryTracker::onGpuContextDestroyed();
}
@@ -85,10 +50,6 @@
return mRenderThread.getGrContext();
}
-void RenderState::flush(Caches::FlushMode mode) {
- if (mCaches) mCaches->flush(mode);
-}
-
void RenderState::onBitmapDestroyed(uint32_t pixelRefId) {
// DEAD CODE
}
@@ -126,42 +87,6 @@
glDeleteFramebuffers(1, &fbo);
}
-void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) {
- if (mode == DrawGlInfo::kModeProcessNoContext) {
- // If there's no context we don't need to interrupt as there's
- // no gl state to save/restore
- (*functor)(mode, info);
- } else {
- interruptForFunctorInvoke();
- (*functor)(mode, info);
- resumeFromFunctorInvoke();
- }
-}
-
-void RenderState::interruptForFunctorInvoke() {
- mCaches->textureState().resetActiveTexture();
- debugOverdraw(false, false);
- // TODO: We need a way to know whether the functor is sRGB aware (b/32072673)
- if (mCaches->extensions().hasLinearBlending() && mCaches->extensions().hasSRGBWriteControl()) {
- glDisable(GL_FRAMEBUFFER_SRGB_EXT);
- }
-}
-
-void RenderState::resumeFromFunctorInvoke() {
- if (mCaches->extensions().hasLinearBlending() && mCaches->extensions().hasSRGBWriteControl()) {
- glEnable(GL_FRAMEBUFFER_SRGB_EXT);
- }
-
- glViewport(0, 0, mViewportWidth, mViewportHeight);
- glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
- debugOverdraw(false, false);
-
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
- mCaches->textureState().activateTexture(0);
- mCaches->textureState().resetBoundTextures();
-}
-
void RenderState::debugOverdraw(bool enable, bool clear) {
// DEAD CODE
}
@@ -190,5 +115,9 @@
// DEAD CODE
}
+renderthread::RenderThread& RenderState::getRenderThread() {
+ return mRenderThread;
+}
+
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 97785a4..f39aa4b 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -16,8 +16,6 @@
#ifndef RENDERSTATE_H
#define RENDERSTATE_H
-#include "Caches.h"
-#include "renderstate/PixelBufferState.h"
#include "utils/Macros.h"
#include <GLES2/gl2.h>
@@ -34,7 +32,6 @@
namespace android {
namespace uirenderer {
-class Caches;
class Layer;
class DeferredLayerUpdater;
@@ -44,22 +41,16 @@
class RenderThread;
}
-// TODO: Replace Cache's GL state tracking with this. For now it's more a thin
// wrapper of Caches for users to migrate to.
class RenderState {
PREVENT_COPY_AND_ASSIGN(RenderState);
friend class renderthread::RenderThread;
- friend class Caches;
friend class renderthread::CacheManager;
public:
- void onGLContextCreated();
- void onGLContextDestroyed();
+ void onContextCreated();
+ void onContextDestroyed();
- void onVkContextCreated();
- void onVkContextDestroyed();
-
- void flush(Caches::FlushMode flushMode);
void onBitmapDestroyed(uint32_t pixelRefId);
void setViewport(GLsizei width, GLsizei height);
@@ -70,8 +61,6 @@
GLuint createFramebuffer();
void deleteFramebuffer(GLuint fbo);
- void invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info);
-
void debugOverdraw(bool enable, bool clear);
void registerLayer(Layer* layer) { mActiveLayers.insert(layer); }
@@ -101,16 +90,15 @@
void dump();
+ renderthread::RenderThread& getRenderThread();
+
private:
- void interruptForFunctorInvoke();
- void resumeFromFunctorInvoke();
void destroyLayersInUpdater();
explicit RenderState(renderthread::RenderThread& thread);
~RenderState();
renderthread::RenderThread& mRenderThread;
- Caches* mCaches = nullptr;
std::set<Layer*> mActiveLayers;
std::set<DeferredLayerUpdater*> mActiveLayerUpdaters;
diff --git a/libs/hwui/renderstate/TextureState.cpp b/libs/hwui/renderstate/TextureState.cpp
deleted file mode 100644
index 470b4f5..0000000
--- a/libs/hwui/renderstate/TextureState.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2015 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 "renderstate/TextureState.h"
-
-#include "Caches.h"
-#include "utils/TraceUtils.h"
-
-#include <GLES3/gl3.h>
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <memory>
-
-namespace android {
-namespace uirenderer {
-
-// Width of mShadowLutTexture, defines how accurate the shadow alpha lookup table is
-static const int SHADOW_LUT_SIZE = 128;
-
-// Must define as many texture units as specified by kTextureUnitsCount
-const GLenum kTextureUnits[] = {GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2, GL_TEXTURE3};
-
-TextureState::TextureState() : mTextureUnit(0) {
- glActiveTexture(kTextureUnits[0]);
- resetBoundTextures();
-
- GLint maxTextureUnits;
- glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
- LOG_ALWAYS_FATAL_IF(maxTextureUnits < kTextureUnitsCount,
- "At least %d texture units are required!", kTextureUnitsCount);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-}
-
-TextureState::~TextureState() {
- if (mShadowLutTexture != nullptr) {
- mShadowLutTexture->deleteTexture();
- }
-}
-
-/**
- * Maps shadow geometry 'alpha' varying (1 for darkest, 0 for transparent) to
- * darkness at that spot. Input values of 0->1 should be mapped within the same
- * range, but can affect the curve for a different visual falloff.
- *
- * This is used to populate the shadow LUT texture for quick lookup in the
- * shadow shader.
- */
-static float computeShadowOpacity(float ratio) {
- // exponential falloff function provided by UX
- float val = 1 - ratio;
- return exp(-val * val * 4.0) - 0.018;
-}
-
-void TextureState::constructTexture(Caches& caches) {
- if (mShadowLutTexture == nullptr) {
- mShadowLutTexture.reset(new Texture(caches));
-
- unsigned char bytes[SHADOW_LUT_SIZE];
- for (int i = 0; i < SHADOW_LUT_SIZE; i++) {
- float inputRatio = i / (SHADOW_LUT_SIZE - 1.0f);
- bytes[i] = computeShadowOpacity(inputRatio) * 255;
- }
- mShadowLutTexture->upload(GL_ALPHA, SHADOW_LUT_SIZE, 1, GL_ALPHA, GL_UNSIGNED_BYTE, &bytes);
- mShadowLutTexture->setFilter(GL_LINEAR);
- mShadowLutTexture->setWrap(GL_CLAMP_TO_EDGE);
- }
-}
-
-void TextureState::activateTexture(GLuint textureUnit) {
- LOG_ALWAYS_FATAL_IF(textureUnit >= kTextureUnitsCount,
- "Tried to use texture unit index %d, only %d exist", textureUnit,
- kTextureUnitsCount);
- if (mTextureUnit != textureUnit) {
- glActiveTexture(kTextureUnits[textureUnit]);
- mTextureUnit = textureUnit;
- }
-}
-
-void TextureState::resetActiveTexture() {
- mTextureUnit = -1;
-}
-
-void TextureState::bindTexture(GLuint texture) {
- if (mBoundTextures[mTextureUnit] != texture) {
- glBindTexture(GL_TEXTURE_2D, texture);
- mBoundTextures[mTextureUnit] = texture;
- }
-}
-
-void TextureState::bindTexture(GLenum target, GLuint texture) {
- if (target == GL_TEXTURE_2D) {
- bindTexture(texture);
- } else {
- // GLConsumer directly calls glBindTexture() with
- // target=GL_TEXTURE_EXTERNAL_OES, don't cache this target
- // since the cached state could be stale
- glBindTexture(target, texture);
- }
-}
-
-void TextureState::deleteTexture(GLuint texture) {
- // When glDeleteTextures() is called on a currently bound texture,
- // OpenGL ES specifies that the texture is then considered unbound
- // Consider the following series of calls:
- //
- // glGenTextures -> creates texture name 2
- // glBindTexture(2)
- // glDeleteTextures(2) -> 2 is now unbound
- // glGenTextures -> can return 2 again
- //
- // If we don't call glBindTexture(2) after the second glGenTextures
- // call, any texture operation will be performed on the default
- // texture (name=0)
-
- unbindTexture(texture);
-
- glDeleteTextures(1, &texture);
-}
-
-void TextureState::resetBoundTextures() {
- for (int i = 0; i < kTextureUnitsCount; i++) {
- mBoundTextures[i] = 0;
- }
-}
-
-void TextureState::unbindTexture(GLuint texture) {
- for (int i = 0; i < kTextureUnitsCount; i++) {
- if (mBoundTextures[i] == texture) {
- mBoundTextures[i] = 0;
- }
- }
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderstate/TextureState.h b/libs/hwui/renderstate/TextureState.h
deleted file mode 100644
index f1996d4..0000000
--- a/libs/hwui/renderstate/TextureState.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2015 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 RENDERSTATE_TEXTURESTATE_H
-#define RENDERSTATE_TEXTURESTATE_H
-
-#include "Texture.h"
-#include "Vertex.h"
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <memory>
-
-namespace android {
-namespace uirenderer {
-
-class Texture;
-
-class TextureState {
- friend class Caches; // TODO: move to RenderState
-public:
- void constructTexture(Caches& caches);
-
- /**
- * Activate the specified texture unit. The texture unit must
- * be specified using an integer number (0 for GL_TEXTURE0 etc.)
- */
- void activateTexture(GLuint textureUnit);
-
- /**
- * Invalidate the cached value of the active texture unit.
- */
- void resetActiveTexture();
-
- /**
- * Binds the specified texture as a GL_TEXTURE_2D texture.
- * All texture bindings must be performed with this method or
- * bindTexture(GLenum, GLuint).
- */
- void bindTexture(GLuint texture);
-
- /**
- * Binds the specified texture with the specified render target.
- * All texture bindings must be performed with this method or
- * bindTexture(GLuint).
- */
- void bindTexture(GLenum target, GLuint texture);
-
- /**
- * Deletes the specified texture and clears it from the cache
- * of bound textures.
- * All textures must be deleted using this method.
- */
- void deleteTexture(GLuint texture);
-
- /**
- * Signals that the cache of bound textures should be cleared.
- * Other users of the context may have altered which textures are bound.
- */
- void resetBoundTextures();
-
- /**
- * Clear the cache of bound textures.
- */
- void unbindTexture(GLuint texture);
-
- Texture* getShadowLutTexture() { return mShadowLutTexture.get(); }
-
-private:
- // total number of texture units available for use
- static const int kTextureUnitsCount = 4;
-
- TextureState();
- ~TextureState();
- GLuint mTextureUnit;
-
- // Caches texture bindings for the GL_TEXTURE_2D target
- GLuint mBoundTextures[kTextureUnitsCount];
-
- std::unique_ptr<Texture> mShadowLutTexture;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif // RENDERSTATE_BLEND_H