blob: 6783503f4ae8d73d18d409cdf06c3185b2c25bb9 [file] [log] [blame]
John Reck3b202512014-06-23 13:13:08 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
John Reck1bcacfd2017-11-03 10:12:19 -070016#include "renderstate/RenderState.h"
17#include <GpuMemoryTracker.h>
sergeyv3e9999b2017-01-19 15:37:02 -080018#include "DeferredLayerUpdater.h"
Greg Daniel8cd3edf2017-01-09 14:15:41 -050019#include "GlLayer.h"
Greg Daniel45ec62b2017-01-04 14:27:00 -050020#include "VkLayer.h"
John Reckd9d7f122018-05-03 14:40:56 -070021#include "Snapshot.h"
John Reck3b202512014-06-23 13:13:08 -070022
John Reck443a7142014-09-04 17:40:05 -070023#include "renderthread/CanvasContext.h"
John Reck0e89e2b2014-10-31 14:49:06 -070024#include "renderthread/EglManager.h"
Chris Craik117bdbc2015-02-05 10:12:38 -080025#include "utils/GLUtils.h"
Romain Guycaaaa662017-03-27 00:40:21 -070026
Chris Craik9db58c02015-08-19 15:19:18 -070027#include <algorithm>
28
Romain Guycaaaa662017-03-27 00:40:21 -070029#include <ui/ColorSpace.h>
30
John Reck3b202512014-06-23 13:13:08 -070031namespace android {
32namespace uirenderer {
33
John Reck0e89e2b2014-10-31 14:49:06 -070034RenderState::RenderState(renderthread::RenderThread& thread)
John Reck1bcacfd2017-11-03 10:12:19 -070035 : mRenderThread(thread), mViewportWidth(0), mViewportHeight(0), mFramebuffer(0) {
John Reck0e89e2b2014-10-31 14:49:06 -070036 mThreadId = pthread_self();
John Reck3b202512014-06-23 13:13:08 -070037}
38
39RenderState::~RenderState() {
40}
41
42void RenderState::onGLContextCreated() {
Greg Daniel45ec62b2017-01-04 14:27:00 -050043 GpuMemoryTracker::onGpuContextCreated();
John Reck38e0c322015-11-10 12:19:17 -080044
John Reck642ebea2017-07-17 09:55:02 -070045 // Deferred because creation needs GL context for texture limits
46 if (!mLayerPool) {
47 mLayerPool = new OffscreenBufferPool();
48 }
49
Chris Craik96a5c4c2015-01-27 15:46:35 -080050 // This is delayed because the first access of Caches makes GL calls
Chris Craikff5c8e82015-01-30 09:46:18 -080051 if (!mCaches) {
52 mCaches = &Caches::createInstance(*this);
53 }
Chris Craik96a5c4c2015-01-27 15:46:35 -080054 mCaches->init();
John Reck3b202512014-06-23 13:13:08 -070055}
56
John Reck49bc4ac2015-01-29 12:53:38 -080057static void layerLostGlContext(Layer* layer) {
Greg Daniel8cd3edf2017-01-09 14:15:41 -050058 LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL,
John Reck1bcacfd2017-11-03 10:12:19 -070059 "layerLostGlContext on non GL layer");
Greg Daniel8cd3edf2017-01-09 14:15:41 -050060 static_cast<GlLayer*>(layer)->onGlContextLost();
John Reck49bc4ac2015-01-29 12:53:38 -080061}
62
Chris Craik1d477422014-08-26 17:30:15 -070063void RenderState::onGLContextDestroyed() {
John Reck642ebea2017-07-17 09:55:02 -070064 mLayerPool->clear();
Chris Craik9fded232015-11-11 16:42:34 -080065
Chris Craik96a5c4c2015-01-27 15:46:35 -080066 // TODO: reset all cached state in state objects
John Reck49bc4ac2015-01-29 12:53:38 -080067 std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext);
Chris Craik96a5c4c2015-01-27 15:46:35 -080068
Chris Craik44eb2c02015-01-29 09:45:09 -080069 mCaches->terminate();
70
sergeyvc3f13162017-02-06 11:45:14 -080071 destroyLayersInUpdater();
Greg Daniel45ec62b2017-01-04 14:27:00 -050072 GpuMemoryTracker::onGpuContextDestroyed();
73}
74
75void RenderState::onVkContextCreated() {
Greg Daniel45ec62b2017-01-04 14:27:00 -050076 GpuMemoryTracker::onGpuContextCreated();
77}
78
79static void layerDestroyedVkContext(Layer* layer) {
80 LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::Vulkan,
81 "layerLostVkContext on non Vulkan layer");
82 static_cast<VkLayer*>(layer)->onVkContextDestroyed();
83}
84
85void RenderState::onVkContextDestroyed() {
Greg Daniel45ec62b2017-01-04 14:27:00 -050086 std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext);
Derek Sollenberger7a4216b2017-10-25 09:52:23 -040087 destroyLayersInUpdater();
Greg Daniel45ec62b2017-01-04 14:27:00 -050088 GpuMemoryTracker::onGpuContextDestroyed();
89}
90
91GrContext* RenderState::getGrContext() const {
92 return mRenderThread.getGrContext();
Chris Craik1d477422014-08-26 17:30:15 -070093}
94
Chris Craik9fded232015-11-11 16:42:34 -080095void RenderState::flush(Caches::FlushMode mode) {
96 switch (mode) {
97 case Caches::FlushMode::Full:
John Reck1bcacfd2017-11-03 10:12:19 -070098 // fall through
Chris Craik9fded232015-11-11 16:42:34 -080099 case Caches::FlushMode::Moderate:
John Reck1bcacfd2017-11-03 10:12:19 -0700100 // fall through
Chris Craik9fded232015-11-11 16:42:34 -0800101 case Caches::FlushMode::Layers:
John Reck642ebea2017-07-17 09:55:02 -0700102 if (mLayerPool) mLayerPool->clear();
Chris Craik9fded232015-11-11 16:42:34 -0800103 break;
104 }
John Reck642ebea2017-07-17 09:55:02 -0700105 if (mCaches) mCaches->flush(mode);
Chris Craik9fded232015-11-11 16:42:34 -0800106}
107
John Reck9a814872017-05-22 15:04:21 -0700108void RenderState::onBitmapDestroyed(uint32_t pixelRefId) {
Mike Reed8cafcc62018-05-03 11:32:46 -0400109 // DEAD CODE
John Reck9a814872017-05-22 15:04:21 -0700110}
111
John Reck3b202512014-06-23 13:13:08 -0700112void RenderState::setViewport(GLsizei width, GLsizei height) {
113 mViewportWidth = width;
114 mViewportHeight = height;
115 glViewport(0, 0, mViewportWidth, mViewportHeight);
116}
117
John Reck3b202512014-06-23 13:13:08 -0700118void RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) {
119 *outWidth = mViewportWidth;
120 *outHeight = mViewportHeight;
121}
122
123void RenderState::bindFramebuffer(GLuint fbo) {
124 if (mFramebuffer != fbo) {
125 mFramebuffer = fbo;
126 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
127 }
128}
129
John Reck0b8d0672016-01-29 14:18:22 -0800130GLuint RenderState::createFramebuffer() {
Chris Craik818c9fb2015-10-23 14:33:42 -0700131 GLuint ret;
132 glGenFramebuffers(1, &ret);
133 return ret;
134}
135
136void RenderState::deleteFramebuffer(GLuint fbo) {
137 if (mFramebuffer == fbo) {
138 // GL defines that deleting the currently bound FBO rebinds FBO 0.
139 // Reflect this in our cached value.
140 mFramebuffer = 0;
141 }
142 glDeleteFramebuffers(1, &fbo);
143}
144
John Reck3b202512014-06-23 13:13:08 -0700145void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) {
John Reck95cd24b2015-08-04 11:17:39 -0700146 if (mode == DrawGlInfo::kModeProcessNoContext) {
147 // If there's no context we don't need to interrupt as there's
148 // no gl state to save/restore
149 (*functor)(mode, info);
150 } else {
151 interruptForFunctorInvoke();
152 (*functor)(mode, info);
153 resumeFromFunctorInvoke();
154 }
John Reck3b202512014-06-23 13:13:08 -0700155}
156
157void RenderState::interruptForFunctorInvoke() {
Chris Craik44eb2c02015-01-29 09:45:09 -0800158 mCaches->textureState().resetActiveTexture();
John Reck3b202512014-06-23 13:13:08 -0700159 debugOverdraw(false, false);
Romain Guy253f2c22016-09-28 17:34:42 -0700160 // TODO: We need a way to know whether the functor is sRGB aware (b/32072673)
John Reck1bcacfd2017-11-03 10:12:19 -0700161 if (mCaches->extensions().hasLinearBlending() && mCaches->extensions().hasSRGBWriteControl()) {
Romain Guy253f2c22016-09-28 17:34:42 -0700162 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
163 }
John Reck3b202512014-06-23 13:13:08 -0700164}
165
166void RenderState::resumeFromFunctorInvoke() {
John Reck1bcacfd2017-11-03 10:12:19 -0700167 if (mCaches->extensions().hasLinearBlending() && mCaches->extensions().hasSRGBWriteControl()) {
Romain Guy253f2c22016-09-28 17:34:42 -0700168 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
169 }
170
John Reck3b202512014-06-23 13:13:08 -0700171 glViewport(0, 0, mViewportWidth, mViewportHeight);
172 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
173 debugOverdraw(false, false);
174
175 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
176
Chris Craik44eb2c02015-01-29 09:45:09 -0800177 mCaches->textureState().activateTexture(0);
178 mCaches->textureState().resetBoundTextures();
John Reck3b202512014-06-23 13:13:08 -0700179}
180
181void RenderState::debugOverdraw(bool enable, bool clear) {
Mike Reede7f688b2018-05-04 15:21:43 -0400182 // DEAD CODE
John Reck3b202512014-06-23 13:13:08 -0700183}
184
sergeyv3e9999b2017-01-19 15:37:02 -0800185static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
186 layerUpdater->destroyLayer();
187}
188
189void RenderState::destroyLayersInUpdater() {
190 std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater);
191}
192
John Reck0e89e2b2014-10-31 14:49:06 -0700193void RenderState::postDecStrong(VirtualLightRefBase* object) {
John Recka55b5d62016-01-14 15:09:10 -0800194 if (pthread_equal(mThreadId, pthread_self())) {
195 object->decStrong(nullptr);
196 } else {
John Reckf8441e62017-10-23 13:10:41 -0700197 mRenderThread.queue().post([object]() { object->decStrong(nullptr); });
John Recka55b5d62016-01-14 15:09:10 -0800198 }
John Reck0e89e2b2014-10-31 14:49:06 -0700199}
200
Chris Craik6c15ffa2015-02-02 13:50:55 -0800201///////////////////////////////////////////////////////////////////////////////
202// Render
203///////////////////////////////////////////////////////////////////////////////
204
Chris Craik117bdbc2015-02-05 10:12:38 -0800205void RenderState::dump() {
Mike Reede7f688b2018-05-04 15:21:43 -0400206 // DEAD CODE
Chris Craik6c15ffa2015-02-02 13:50:55 -0800207}
208
John Reck3b202512014-06-23 13:13:08 -0700209} /* namespace uirenderer */
210} /* namespace android */