summaryrefslogtreecommitdiff
path: root/libs/hwui/renderstate/RenderState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/renderstate/RenderState.cpp')
-rw-r--r--libs/hwui/renderstate/RenderState.cpp138
1 files changed, 97 insertions, 41 deletions
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 2a3a9f3635ca..2c92924cc12c 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -13,14 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "DeferredLayerUpdater.h"
+#include "GlLayer.h"
+#include "VkLayer.h"
#include <GpuMemoryTracker.h>
#include "renderstate/RenderState.h"
#include "renderthread/CanvasContext.h"
#include "renderthread/EglManager.h"
#include "utils/GLUtils.h"
+
#include <algorithm>
+#include <ui/ColorSpace.h>
+
namespace android {
namespace uirenderer {
@@ -40,7 +46,7 @@ RenderState::~RenderState() {
void RenderState::onGLContextCreated() {
LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
"State object lifecycle not managed correctly");
- GpuMemoryTracker::onGLContextCreated();
+ GpuMemoryTracker::onGpuContextCreated();
mBlend = new Blend();
mMeshState = new MeshState();
@@ -52,51 +58,19 @@ void RenderState::onGLContextCreated() {
mCaches = &Caches::createInstance(*this);
}
mCaches->init();
- mCaches->textureCache.setAssetAtlas(&mAssetAtlas);
}
static void layerLostGlContext(Layer* layer) {
- layer->onGlContextLost();
+ LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL,
+ "layerLostGlContext on non GL layer");
+ static_cast<GlLayer*>(layer)->onGlContextLost();
}
void RenderState::onGLContextDestroyed() {
-/*
- size_t size = mActiveLayers.size();
- if (CC_UNLIKELY(size != 0)) {
- ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
- mRegisteredContexts.size(), size, mActiveLayers.empty());
- mCaches->dumpMemoryUsage();
- for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin();
- cit != mRegisteredContexts.end(); cit++) {
- renderthread::CanvasContext* context = *cit;
- ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get());
- ALOGE(" Prefeteched layers: %zu", context->mPrefetechedLayers.size());
- for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin();
- pit != context->mPrefetechedLayers.end(); pit++) {
- (*pit)->debugDumpLayers(" ");
- }
- context->mRootRenderNode->debugDumpLayers(" ");
- }
-
-
- if (mActiveLayers.begin() == mActiveLayers.end()) {
- ALOGE("set has become empty. wat.");
- }
- for (std::set<const Layer*>::iterator lit = mActiveLayers.begin();
- lit != mActiveLayers.end(); lit++) {
- const Layer* layer = *(lit);
- ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d",
- layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered);
- }
- LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
- }
-*/
-
mLayerPool.clear();
// TODO: reset all cached state in state objects
std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext);
- mAssetAtlas.terminate();
mCaches->terminate();
@@ -109,7 +83,30 @@ void RenderState::onGLContextDestroyed() {
delete mStencil;
mStencil = nullptr;
- GpuMemoryTracker::onGLContextDestroyed();
+ destroyLayersInUpdater();
+ GpuMemoryTracker::onGpuContextDestroyed();
+}
+
+void RenderState::onVkContextCreated() {
+ LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
+ "State object lifecycle not managed correctly");
+ 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() {
+ mLayerPool.clear();
+ std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext);
+ GpuMemoryTracker::onGpuContextDestroyed();
+}
+
+GrContext* RenderState::getGrContext() const {
+ return mRenderThread.getGrContext();
}
void RenderState::flush(Caches::FlushMode mode) {
@@ -125,6 +122,13 @@ void RenderState::flush(Caches::FlushMode mode) {
mCaches->flush(mode);
}
+void RenderState::onBitmapDestroyed(uint32_t pixelRefId) {
+ if (mCaches && mCaches->textureCache.destroyTexture(pixelRefId)) {
+ glFlush();
+ GL_CHECKPOINT(MODERATE);
+ }
+}
+
void RenderState::setViewport(GLsizei width, GLsizei height) {
mViewportWidth = width;
mViewportHeight = height;
@@ -179,9 +183,19 @@ void RenderState::interruptForFunctorInvoke() {
meshState().resetVertexPointers();
meshState().disableTexCoordsVertexArray();
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);
@@ -209,6 +223,14 @@ void RenderState::debugOverdraw(bool enable, bool clear) {
}
}
+static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
+ layerUpdater->destroyLayer();
+}
+
+void RenderState::destroyLayersInUpdater() {
+ std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater);
+}
+
class DecStrongTask : public renderthread::RenderTask {
public:
explicit DecStrongTask(VirtualLightRefBase* object) : mObject(object) {}
@@ -310,12 +332,12 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) {
// texture always takes slot 0, shader samplers increment from there
mCaches->textureState().activateTexture(0);
- mCaches->textureState().bindTexture(texture.target, texture.texture->id());
+ mCaches->textureState().bindTexture(texture.texture->target(), texture.texture->id());
if (texture.clamp != GL_INVALID_ENUM) {
- texture.texture->setWrap(texture.clamp, false, false, texture.target);
+ texture.texture->setWrap(texture.clamp, false, false);
}
if (texture.filter != GL_INVALID_ENUM) {
- texture.texture->setFilter(texture.filter, false, false, texture.target);
+ texture.texture->setFilter(texture.filter, false, false);
}
if (texture.textureTransform) {
@@ -346,13 +368,47 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) {
glVertexAttribPointer(alphaLocation, 1, GL_FLOAT, GL_FALSE, vertices.stride, alphaCoords);
}
// Shader uniforms
- SkiaShader::apply(*mCaches, fill.skiaShaderData);
+ SkiaShader::apply(*mCaches, fill.skiaShaderData, mViewportWidth, mViewportHeight);
GL_CHECKPOINT(MODERATE);
Texture* texture = (fill.skiaShaderData.skiaShaderType & kBitmap_SkiaShaderType) ?
fill.skiaShaderData.bitmapData.bitmapTexture : nullptr;
const AutoTexture autoCleanup(texture);
+ // If we have a shader and a base texture, the base texture is assumed to be an alpha mask
+ // which means the color space conversion applies to the shader's bitmap
+ Texture* colorSpaceTexture = texture != nullptr ? texture : fill.texture.texture;
+ if (colorSpaceTexture != nullptr) {
+ if (colorSpaceTexture->hasColorSpaceConversion()) {
+ const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector();
+ glUniformMatrix3fv(fill.program->getUniform("colorSpaceMatrix"), 1,
+ GL_FALSE, connector->getTransform().asArray());
+ }
+
+ TransferFunctionType transferFunction = colorSpaceTexture->getTransferFunctionType();
+ if (transferFunction != TransferFunctionType::None) {
+ const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector();
+ const ColorSpace& source = connector->getSource();
+
+ switch (transferFunction) {
+ case TransferFunctionType::None:
+ break;
+ case TransferFunctionType::Full:
+ glUniform1fv(fill.program->getUniform("transferFunction"), 7,
+ reinterpret_cast<const float*>(&source.getTransferParameters().g));
+ break;
+ case TransferFunctionType::Limited:
+ glUniform1fv(fill.program->getUniform("transferFunction"), 5,
+ reinterpret_cast<const float*>(&source.getTransferParameters().g));
+ break;
+ case TransferFunctionType::Gamma:
+ glUniform1f(fill.program->getUniform("transferFunctionGamma"),
+ source.getTransferParameters().g);
+ break;
+ }
+ }
+ }
+
// ------------------------------------
// ---------- GL state setup ----------
// ------------------------------------