PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/frameworks/base/libs/hwui/Caches.cpp

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk
C++ | 526 lines | 395 code | 86 blank | 45 comment | 61 complexity | f9e196a904521d7cd379902667a30e5d MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 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. */
  16. #define LOG_TAG "OpenGLRenderer"
  17. #include <utils/Log.h>
  18. #include <utils/String8.h>
  19. #include "Caches.h"
  20. #include "DisplayListRenderer.h"
  21. #include "Properties.h"
  22. #include "LayerRenderer.h"
  23. namespace android {
  24. #ifdef USE_OPENGL_RENDERER
  25. using namespace uirenderer;
  26. ANDROID_SINGLETON_STATIC_INSTANCE(Caches);
  27. #endif
  28. namespace uirenderer {
  29. ///////////////////////////////////////////////////////////////////////////////
  30. // Macros
  31. ///////////////////////////////////////////////////////////////////////////////
  32. #if DEBUG_CACHE_FLUSH
  33. #define FLUSH_LOGD(...) ALOGD(__VA_ARGS__)
  34. #else
  35. #define FLUSH_LOGD(...)
  36. #endif
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // Constructors/destructor
  39. ///////////////////////////////////////////////////////////////////////////////
  40. Caches::Caches(): Singleton<Caches>(), mInitialized(false) {
  41. init();
  42. initFont();
  43. initExtensions();
  44. initConstraints();
  45. initProperties();
  46. mDebugLevel = readDebugLevel();
  47. ALOGD("Enabling debug mode %d", mDebugLevel);
  48. }
  49. void Caches::init() {
  50. if (mInitialized) return;
  51. glGenBuffers(1, &meshBuffer);
  52. glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
  53. glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
  54. mCurrentBuffer = meshBuffer;
  55. mCurrentIndicesBuffer = 0;
  56. mCurrentPositionPointer = this;
  57. mCurrentPositionStride = 0;
  58. mCurrentTexCoordsPointer = this;
  59. mTexCoordsArrayEnabled = false;
  60. glDisable(GL_SCISSOR_TEST);
  61. scissorEnabled = false;
  62. mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
  63. glActiveTexture(gTextureUnits[0]);
  64. mTextureUnit = 0;
  65. mRegionMesh = NULL;
  66. blend = false;
  67. lastSrcMode = GL_ZERO;
  68. lastDstMode = GL_ZERO;
  69. currentProgram = NULL;
  70. mFunctorsCount = 0;
  71. mInitialized = true;
  72. }
  73. void Caches::initFont() {
  74. fontRenderer = GammaFontRenderer::createRenderer();
  75. }
  76. void Caches::initExtensions() {
  77. if (extensions.hasDebugMarker()) {
  78. eventMark = glInsertEventMarkerEXT;
  79. startMark = glPushGroupMarkerEXT;
  80. endMark = glPopGroupMarkerEXT;
  81. } else {
  82. eventMark = eventMarkNull;
  83. startMark = startMarkNull;
  84. endMark = endMarkNull;
  85. }
  86. if (extensions.hasDebugLabel()) {
  87. setLabel = glLabelObjectEXT;
  88. getLabel = glGetObjectLabelEXT;
  89. } else {
  90. setLabel = setLabelNull;
  91. getLabel = getLabelNull;
  92. }
  93. }
  94. void Caches::initConstraints() {
  95. GLint maxTextureUnits;
  96. glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
  97. if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
  98. ALOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
  99. }
  100. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
  101. }
  102. void Caches::initProperties() {
  103. char property[PROPERTY_VALUE_MAX];
  104. if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, NULL) > 0) {
  105. INIT_LOGD(" Layers updates debug enabled: %s", property);
  106. debugLayersUpdates = !strcmp(property, "true");
  107. } else {
  108. debugLayersUpdates = false;
  109. }
  110. if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) {
  111. INIT_LOGD(" Overdraw debug enabled: %s", property);
  112. debugOverdraw = !strcmp(property, "true");
  113. } else {
  114. debugOverdraw = false;
  115. }
  116. }
  117. void Caches::terminate() {
  118. if (!mInitialized) return;
  119. glDeleteBuffers(1, &meshBuffer);
  120. mCurrentBuffer = 0;
  121. glDeleteBuffers(1, &mRegionMeshIndices);
  122. delete[] mRegionMesh;
  123. mRegionMesh = NULL;
  124. fboCache.clear();
  125. programCache.clear();
  126. currentProgram = NULL;
  127. mInitialized = false;
  128. }
  129. ///////////////////////////////////////////////////////////////////////////////
  130. // Debug
  131. ///////////////////////////////////////////////////////////////////////////////
  132. void Caches::dumpMemoryUsage() {
  133. String8 stringLog;
  134. dumpMemoryUsage(stringLog);
  135. ALOGD("%s", stringLog.string());
  136. }
  137. void Caches::dumpMemoryUsage(String8 &log) {
  138. log.appendFormat("Current memory usage / total memory usage (bytes):\n");
  139. log.appendFormat(" TextureCache %8d / %8d\n",
  140. textureCache.getSize(), textureCache.getMaxSize());
  141. log.appendFormat(" LayerCache %8d / %8d\n",
  142. layerCache.getSize(), layerCache.getMaxSize());
  143. log.appendFormat(" GradientCache %8d / %8d\n",
  144. gradientCache.getSize(), gradientCache.getMaxSize());
  145. log.appendFormat(" PathCache %8d / %8d\n",
  146. pathCache.getSize(), pathCache.getMaxSize());
  147. log.appendFormat(" CircleShapeCache %8d / %8d\n",
  148. circleShapeCache.getSize(), circleShapeCache.getMaxSize());
  149. log.appendFormat(" OvalShapeCache %8d / %8d\n",
  150. ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
  151. log.appendFormat(" RoundRectShapeCache %8d / %8d\n",
  152. roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
  153. log.appendFormat(" RectShapeCache %8d / %8d\n",
  154. rectShapeCache.getSize(), rectShapeCache.getMaxSize());
  155. log.appendFormat(" ArcShapeCache %8d / %8d\n",
  156. arcShapeCache.getSize(), arcShapeCache.getMaxSize());
  157. log.appendFormat(" TextDropShadowCache %8d / %8d\n", dropShadowCache.getSize(),
  158. dropShadowCache.getMaxSize());
  159. for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
  160. const uint32_t size = fontRenderer->getFontRendererSize(i);
  161. log.appendFormat(" FontRenderer %d %8d / %8d\n", i, size, size);
  162. }
  163. log.appendFormat("Other:\n");
  164. log.appendFormat(" FboCache %8d / %8d\n",
  165. fboCache.getSize(), fboCache.getMaxSize());
  166. log.appendFormat(" PatchCache %8d / %8d\n",
  167. patchCache.getSize(), patchCache.getMaxSize());
  168. uint32_t total = 0;
  169. total += textureCache.getSize();
  170. total += layerCache.getSize();
  171. total += gradientCache.getSize();
  172. total += pathCache.getSize();
  173. total += dropShadowCache.getSize();
  174. total += roundRectShapeCache.getSize();
  175. total += circleShapeCache.getSize();
  176. total += ovalShapeCache.getSize();
  177. total += rectShapeCache.getSize();
  178. total += arcShapeCache.getSize();
  179. for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
  180. total += fontRenderer->getFontRendererSize(i);
  181. }
  182. log.appendFormat("Total memory usage:\n");
  183. log.appendFormat(" %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
  184. }
  185. ///////////////////////////////////////////////////////////////////////////////
  186. // Memory management
  187. ///////////////////////////////////////////////////////////////////////////////
  188. void Caches::clearGarbage() {
  189. textureCache.clearGarbage();
  190. pathCache.clearGarbage();
  191. Vector<DisplayList*> displayLists;
  192. Vector<Layer*> layers;
  193. { // scope for the lock
  194. Mutex::Autolock _l(mGarbageLock);
  195. displayLists = mDisplayListGarbage;
  196. layers = mLayerGarbage;
  197. mDisplayListGarbage.clear();
  198. mLayerGarbage.clear();
  199. }
  200. size_t count = displayLists.size();
  201. for (size_t i = 0; i < count; i++) {
  202. DisplayList* displayList = displayLists.itemAt(i);
  203. delete displayList;
  204. }
  205. count = layers.size();
  206. for (size_t i = 0; i < count; i++) {
  207. Layer* layer = layers.itemAt(i);
  208. delete layer;
  209. }
  210. layers.clear();
  211. }
  212. void Caches::deleteLayerDeferred(Layer* layer) {
  213. Mutex::Autolock _l(mGarbageLock);
  214. mLayerGarbage.push(layer);
  215. }
  216. void Caches::deleteDisplayListDeferred(DisplayList* displayList) {
  217. Mutex::Autolock _l(mGarbageLock);
  218. mDisplayListGarbage.push(displayList);
  219. }
  220. void Caches::flush(FlushMode mode) {
  221. FLUSH_LOGD("Flushing caches (mode %d)", mode);
  222. switch (mode) {
  223. case kFlushMode_Full:
  224. textureCache.clear();
  225. patchCache.clear();
  226. dropShadowCache.clear();
  227. gradientCache.clear();
  228. fontRenderer->clear();
  229. dither.clear();
  230. // fall through
  231. case kFlushMode_Moderate:
  232. fontRenderer->flush();
  233. textureCache.flush();
  234. pathCache.clear();
  235. roundRectShapeCache.clear();
  236. circleShapeCache.clear();
  237. ovalShapeCache.clear();
  238. rectShapeCache.clear();
  239. arcShapeCache.clear();
  240. // fall through
  241. case kFlushMode_Layers:
  242. layerCache.clear();
  243. break;
  244. }
  245. clearGarbage();
  246. }
  247. ///////////////////////////////////////////////////////////////////////////////
  248. // VBO
  249. ///////////////////////////////////////////////////////////////////////////////
  250. bool Caches::bindMeshBuffer() {
  251. return bindMeshBuffer(meshBuffer);
  252. }
  253. bool Caches::bindMeshBuffer(const GLuint buffer) {
  254. if (mCurrentBuffer != buffer) {
  255. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  256. mCurrentBuffer = buffer;
  257. return true;
  258. }
  259. return false;
  260. }
  261. bool Caches::unbindMeshBuffer() {
  262. if (mCurrentBuffer) {
  263. glBindBuffer(GL_ARRAY_BUFFER, 0);
  264. mCurrentBuffer = 0;
  265. return true;
  266. }
  267. return false;
  268. }
  269. bool Caches::bindIndicesBuffer(const GLuint buffer) {
  270. if (mCurrentIndicesBuffer != buffer) {
  271. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
  272. mCurrentIndicesBuffer = buffer;
  273. return true;
  274. }
  275. return false;
  276. }
  277. bool Caches::unbindIndicesBuffer() {
  278. if (mCurrentIndicesBuffer) {
  279. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  280. mCurrentIndicesBuffer = 0;
  281. return true;
  282. }
  283. return false;
  284. }
  285. ///////////////////////////////////////////////////////////////////////////////
  286. // Meshes and textures
  287. ///////////////////////////////////////////////////////////////////////////////
  288. void Caches::bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei stride) {
  289. if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
  290. GLuint slot = currentProgram->position;
  291. glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
  292. mCurrentPositionPointer = vertices;
  293. mCurrentPositionStride = stride;
  294. }
  295. }
  296. void Caches::bindTexCoordsVertexPointer(bool force, GLvoid* vertices) {
  297. if (force || vertices != mCurrentTexCoordsPointer) {
  298. GLuint slot = currentProgram->texCoords;
  299. glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, gMeshStride, vertices);
  300. mCurrentTexCoordsPointer = vertices;
  301. }
  302. }
  303. void Caches::resetVertexPointers() {
  304. mCurrentPositionPointer = this;
  305. mCurrentTexCoordsPointer = this;
  306. }
  307. void Caches::resetTexCoordsVertexPointer() {
  308. mCurrentTexCoordsPointer = this;
  309. }
  310. void Caches::enableTexCoordsVertexArray() {
  311. if (!mTexCoordsArrayEnabled) {
  312. glEnableVertexAttribArray(Program::kBindingTexCoords);
  313. mCurrentTexCoordsPointer = this;
  314. mTexCoordsArrayEnabled = true;
  315. }
  316. }
  317. void Caches::disbaleTexCoordsVertexArray() {
  318. if (mTexCoordsArrayEnabled) {
  319. glDisableVertexAttribArray(Program::kBindingTexCoords);
  320. mTexCoordsArrayEnabled = false;
  321. }
  322. }
  323. void Caches::activeTexture(GLuint textureUnit) {
  324. if (mTextureUnit != textureUnit) {
  325. glActiveTexture(gTextureUnits[textureUnit]);
  326. mTextureUnit = textureUnit;
  327. }
  328. }
  329. ///////////////////////////////////////////////////////////////////////////////
  330. // Scissor
  331. ///////////////////////////////////////////////////////////////////////////////
  332. bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
  333. if (scissorEnabled && (x != mScissorX || y != mScissorY ||
  334. width != mScissorWidth || height != mScissorHeight)) {
  335. if (x < 0) {
  336. width += x;
  337. x = 0;
  338. }
  339. if (y < 0) {
  340. height += y;
  341. y = 0;
  342. }
  343. if (width < 0) {
  344. width = 0;
  345. }
  346. if (height < 0) {
  347. height = 0;
  348. }
  349. glScissor(x, y, width, height);
  350. mScissorX = x;
  351. mScissorY = y;
  352. mScissorWidth = width;
  353. mScissorHeight = height;
  354. return true;
  355. }
  356. return false;
  357. }
  358. bool Caches::enableScissor() {
  359. if (!scissorEnabled) {
  360. glEnable(GL_SCISSOR_TEST);
  361. scissorEnabled = true;
  362. resetScissor();
  363. return true;
  364. }
  365. return false;
  366. }
  367. bool Caches::disableScissor() {
  368. if (scissorEnabled) {
  369. glDisable(GL_SCISSOR_TEST);
  370. scissorEnabled = false;
  371. return true;
  372. }
  373. return false;
  374. }
  375. void Caches::setScissorEnabled(bool enabled) {
  376. if (scissorEnabled != enabled) {
  377. if (enabled) glEnable(GL_SCISSOR_TEST);
  378. else glDisable(GL_SCISSOR_TEST);
  379. scissorEnabled = enabled;
  380. }
  381. }
  382. void Caches::resetScissor() {
  383. mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
  384. }
  385. ///////////////////////////////////////////////////////////////////////////////
  386. // Tiling
  387. ///////////////////////////////////////////////////////////////////////////////
  388. void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) {
  389. if (extensions.hasTiledRendering() && !debugOverdraw) {
  390. glStartTilingQCOM(x, y, width, height, (opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
  391. }
  392. }
  393. void Caches::endTiling() {
  394. if (extensions.hasTiledRendering() && !debugOverdraw) {
  395. glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
  396. }
  397. }
  398. bool Caches::hasRegisteredFunctors() {
  399. return mFunctorsCount > 0;
  400. }
  401. void Caches::registerFunctors(uint32_t functorCount) {
  402. mFunctorsCount += functorCount;
  403. }
  404. void Caches::unregisterFunctors(uint32_t functorCount) {
  405. if (functorCount > mFunctorsCount) {
  406. mFunctorsCount = 0;
  407. } else {
  408. mFunctorsCount -= functorCount;
  409. }
  410. }
  411. ///////////////////////////////////////////////////////////////////////////////
  412. // Regions
  413. ///////////////////////////////////////////////////////////////////////////////
  414. TextureVertex* Caches::getRegionMesh() {
  415. // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
  416. if (!mRegionMesh) {
  417. mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
  418. uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
  419. for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
  420. uint16_t quad = i * 4;
  421. int index = i * 6;
  422. regionIndices[index ] = quad; // top-left
  423. regionIndices[index + 1] = quad + 1; // top-right
  424. regionIndices[index + 2] = quad + 2; // bottom-left
  425. regionIndices[index + 3] = quad + 2; // bottom-left
  426. regionIndices[index + 4] = quad + 1; // top-right
  427. regionIndices[index + 5] = quad + 3; // bottom-right
  428. }
  429. glGenBuffers(1, &mRegionMeshIndices);
  430. bindIndicesBuffer(mRegionMeshIndices);
  431. glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
  432. regionIndices, GL_STATIC_DRAW);
  433. delete[] regionIndices;
  434. } else {
  435. bindIndicesBuffer(mRegionMeshIndices);
  436. }
  437. return mRegionMesh;
  438. }
  439. }; // namespace uirenderer
  440. }; // namespace android