diff options
author | John Reck <jreck@google.com> | 2018-08-30 16:47:59 +0000 |
---|---|---|
committer | Stan Iliev <stani@google.com> | 2018-08-30 18:42:08 +0000 |
commit | 867c43de0544217d26c3ee18f4d6603bb2ea97ce (patch) | |
tree | d780e25edaa90578c80309a105d6fe2e9eea71c8 /libs/hwui/renderstate | |
parent | c8e22a653297837da9a80b0ba65f6854c8986c96 (diff) |
Revert "TextureView Vulkan support and optimized OpenGL draw"
This reverts commit c8e22a653297837da9a80b0ba65f6854c8986c96.
Reason for revert: broke camera, b/113555199
Bug: 113555199
Change-Id: Iae9b462694d5de0cd99427afead63b567fb4d71d
Diffstat (limited to 'libs/hwui/renderstate')
-rw-r--r-- | libs/hwui/renderstate/PixelBufferState.cpp | 42 | ||||
-rw-r--r-- | libs/hwui/renderstate/PixelBufferState.h | 38 | ||||
-rw-r--r-- | libs/hwui/renderstate/RenderState.cpp | 83 | ||||
-rw-r--r-- | libs/hwui/renderstate/RenderState.h | 20 | ||||
-rw-r--r-- | libs/hwui/renderstate/TextureState.cpp | 147 | ||||
-rw-r--r-- | libs/hwui/renderstate/TextureState.h | 98 |
6 files changed, 418 insertions, 10 deletions
diff --git a/libs/hwui/renderstate/PixelBufferState.cpp b/libs/hwui/renderstate/PixelBufferState.cpp new file mode 100644 index 000000000000..3a6efb833c47 --- /dev/null +++ b/libs/hwui/renderstate/PixelBufferState.cpp @@ -0,0 +1,42 @@ +/* + * 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 new file mode 100644 index 000000000000..f7ae6c575f6a --- /dev/null +++ b/libs/hwui/renderstate/PixelBufferState.h @@ -0,0 +1,38 @@ +/* + * 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 b524bcb096da..3be84f588a20 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -16,6 +16,8 @@ #include "renderstate/RenderState.h" #include <GpuMemoryTracker.h> #include "DeferredLayerUpdater.h" +#include "GlLayer.h" +#include "VkLayer.h" #include "Snapshot.h" #include "renderthread/CanvasContext.h" @@ -37,11 +39,44 @@ RenderState::RenderState(renderthread::RenderThread& thread) RenderState::~RenderState() { } -void RenderState::onContextCreated() { +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(); } -void RenderState::onContextDestroyed() { +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() { + 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); destroyLayersInUpdater(); GpuMemoryTracker::onGpuContextDestroyed(); } @@ -50,6 +85,10 @@ GrContext* RenderState::getGrContext() const { return mRenderThread.getGrContext(); } +void RenderState::flush(Caches::FlushMode mode) { + if (mCaches) mCaches->flush(mode); +} + void RenderState::onBitmapDestroyed(uint32_t pixelRefId) { // DEAD CODE } @@ -87,6 +126,42 @@ void RenderState::deleteFramebuffer(GLuint fbo) { 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 } @@ -115,9 +190,5 @@ void RenderState::dump() { // 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 f39aa4b96547..97785a46dcd7 100644 --- a/libs/hwui/renderstate/RenderState.h +++ b/libs/hwui/renderstate/RenderState.h @@ -16,6 +16,8 @@ #ifndef RENDERSTATE_H #define RENDERSTATE_H +#include "Caches.h" +#include "renderstate/PixelBufferState.h" #include "utils/Macros.h" #include <GLES2/gl2.h> @@ -32,6 +34,7 @@ class GrContext; namespace android { namespace uirenderer { +class Caches; class Layer; class DeferredLayerUpdater; @@ -41,16 +44,22 @@ class CanvasContext; 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 onContextCreated(); - void onContextDestroyed(); + void onGLContextCreated(); + void onGLContextDestroyed(); + void onVkContextCreated(); + void onVkContextDestroyed(); + + void flush(Caches::FlushMode flushMode); void onBitmapDestroyed(uint32_t pixelRefId); void setViewport(GLsizei width, GLsizei height); @@ -61,6 +70,8 @@ public: 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); } @@ -90,15 +101,16 @@ public: 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 new file mode 100644 index 000000000000..470b4f5de97f --- /dev/null +++ b/libs/hwui/renderstate/TextureState.cpp @@ -0,0 +1,147 @@ +/* + * 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 new file mode 100644 index 000000000000..f1996d431fa2 --- /dev/null +++ b/libs/hwui/renderstate/TextureState.h @@ -0,0 +1,98 @@ +/* + * 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 |