OpenGLRenderer.cpp revision 7fac2e18339f765320d759e8d4c090f92431959e
1603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/* 2603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Copyright (C) 2010 The Android Open Source Project 3603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 4603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Licensed under the Apache License, Version 2.0 (the "License"); 5603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * you may not use this file except in compliance with the License. 6603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * You may obtain a copy of the License at 7603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 8603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * http://www.apache.org/licenses/LICENSE-2.0 9603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * 10603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * Unless required by applicable law or agreed to in writing, software 11603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * distributed under the License is distributed on an "AS IS" BASIS, 12603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * See the License for the specific language governing permissions and 14603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana * limitations under the License. 15603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana */ 16603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 177a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey#define LOG_TAG "OpenGLRenderer" 18603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 197a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey#include <stdlib.h> 207a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey#include <stdint.h> 2156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana#include <sys/types.h> 2256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana#include <SkCanvas.h> 2456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana#include <cutils/properties.h> 2656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana#include <utils/Log.h> 2756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn#include "OpenGLRenderer.h" 29603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 30603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintananamespace android { 3156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintananamespace uirenderer { 32603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 3356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana/////////////////////////////////////////////////////////////////////////////// 3456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana// Defines 35603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/////////////////////////////////////////////////////////////////////////////// 3656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 3756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana// These properties are defined in mega-bytes 3856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size" 39603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size" 4056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 41603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define DEFAULT_TEXTURE_CACHE_SIZE 20 42603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define DEFAULT_LAYER_CACHE_SIZE 10 43603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define DEFAULT_PATCH_CACHE_SIZE 100 4456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 4556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana// Converts a number of mega-bytes into bytes 46603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define MB(s) s * 1024 * 1024 47603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 48603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana// Generates simple and textured vertices 49603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define SV(x, y) { { x, y } } 50603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana#define FV(x, y, u, v) { { x, y }, { u, v } } 5156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 52603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/////////////////////////////////////////////////////////////////////////////// 53603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana// Globals 54603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/////////////////////////////////////////////////////////////////////////////// 55603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 5656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanastatic const SimpleVertex gDrawColorVertices[] = { 5756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana SV(0.0f, 0.0f), 58603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SV(1.0f, 0.0f), 59603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SV(0.0f, 1.0f), 60603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana SV(1.0f, 1.0f) 61603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana}; 62603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanastatic const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); 63603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanastatic const GLsizei gDrawColorVertexCount = 4; 64603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 653710f390968e683a0ad3adf0b517dfcade3564ceFred Quintana// This array is never used directly but used as a memcpy source in the 66603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana// OpenGLRenderer constructor 673710f390968e683a0ad3adf0b517dfcade3564ceFred Quintanastatic const TextureVertex gDrawTextureVertices[] = { 68603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana FV(0.0f, 0.0f, 0.0f, 0.0f), 69603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana FV(1.0f, 0.0f, 1.0f, 0.0f), 70603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana FV(0.0f, 1.0f, 0.0f, 1.0f), 71603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana FV(1.0f, 1.0f, 1.0f, 1.0f) 72603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana}; 73603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanastatic const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); 74603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanastatic const GLsizei gDrawTextureVertexCount = 4; 75603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 76603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana// In this array, the index of each Blender equals the value of the first 77603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana// entry. For instance, gBlends[1] == gBlends[SkXfermode::kSrc_Mode] 7831c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasanistatic const Blender gBlends[] = { 7931c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani { SkXfermode::kClear_Mode, GL_ZERO, GL_ZERO }, 8031c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani { SkXfermode::kSrc_Mode, GL_ONE, GL_ZERO }, 8131c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani { SkXfermode::kDst_Mode, GL_ZERO, GL_ONE }, 8231c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani { SkXfermode::kSrcOver_Mode, GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, 8331c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani { SkXfermode::kDstOver_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE }, 8456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana { SkXfermode::kSrcIn_Mode, GL_DST_ALPHA, GL_ZERO }, 8556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana { SkXfermode::kDstIn_Mode, GL_ZERO, GL_SRC_ALPHA }, 86603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana { SkXfermode::kSrcOut_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, 87603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana { SkXfermode::kDstOut_Mode, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, 88603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana { SkXfermode::kSrcATop_Mode, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, 89603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana { SkXfermode::kDstATop_Mode, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, 90603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana { SkXfermode::kXor_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA } 91603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana}; 92603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 93603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintanastatic const GLint gTileModes[] = { 94603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode 9556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana GL_REPEAT, // == SkShader::kRepeat_Mode 96603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode 97603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana}; 98603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 99603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/////////////////////////////////////////////////////////////////////////////// 100603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana// Constructors/destructor 101603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana/////////////////////////////////////////////////////////////////////////////// 102f9f240e3ad5ff5eeaa32fbb2dd65ef7f3b06af32Fred Quintana 103603073430bbcb1bd29db7afb9b14e2732ad589fbFred QuintanaOpenGLRenderer::OpenGLRenderer(): 10456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mBlend(false), mLastSrcMode(GL_ZERO), mLastDstMode(GL_ZERO), 105603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mTextureCache(MB(DEFAULT_TEXTURE_CACHE_SIZE)), 106603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)), 107603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mPatchCache(DEFAULT_PATCH_CACHE_SIZE) { 108603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana LOGD("Create OpenGLRenderer"); 109603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 110603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana char property[PROPERTY_VALUE_MAX]; 111603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) { 112603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana LOGD(" Setting texture cache size to %sMB", property); 113603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mTextureCache.setMaxSize(MB(atoi(property))); 11431c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani } else { 11531c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani LOGD(" Using default texture cache size of %dMB", DEFAULT_TEXTURE_CACHE_SIZE); 116603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } 11756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 11856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, NULL) > 0) { 119603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana LOGD(" Setting layer cache size to %sMB", property); 12056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mLayerCache.setMaxSize(MB(atoi(property))); 121603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana } else { 12256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana LOGD(" Using default layer cache size of %dMB", DEFAULT_LAYER_CACHE_SIZE); 12356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 124603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 125603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mDrawColorProgram = new DrawColorProgram; 126603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mDrawTextureProgram = new DrawTextureProgram; 127603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mCurrentProgram = mDrawTextureProgram; 128603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 129603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mShader = kShaderNone; 130603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mShaderTileX = SkShader::kClamp_TileMode; 131603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mShaderTileY = SkShader::kClamp_TileMode; 132603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mShaderMatrix = NULL; 133603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mShaderBitmap = NULL; 134603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 135603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mLastTexture = 0; 136603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 13731c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani memcpy(mDrawTextureVertices, gDrawTextureVertices, sizeof(gDrawTextureVertices)); 13831c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani} 13956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 14056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred QuintanaOpenGLRenderer::~OpenGLRenderer() { 14156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana LOGD("Destroy OpenGLRenderer"); 14256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 14356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mTextureCache.clear(); 14456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mLayerCache.clear(); 14556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mPatchCache.clear(); 14656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 14756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 14856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana/////////////////////////////////////////////////////////////////////////////// 14956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana// Setup 15056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana/////////////////////////////////////////////////////////////////////////////// 15156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 15256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanavoid OpenGLRenderer::setViewport(int width, int height) { 15356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glViewport(0, 0, width, height); 15456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 15556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 156603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 157603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mWidth = width; 158603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mHeight = height; 159603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana mFirstSnapshot.height = height; 160603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana} 16131c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasani 16231c0959b1a04f4e17d7528a6e4a9296701e3ade7Amith Yamasanivoid OpenGLRenderer::prepare() { 16356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mSnapshot = &mFirstSnapshot; 16456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mSaveCount = 0; 16556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 16656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glDisable(GL_SCISSOR_TEST); 16756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 16856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 16956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glClear(GL_COLOR_BUFFER_BIT); 17056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 17156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glEnable(GL_SCISSOR_TEST); 17256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glScissor(0, 0, mWidth, mHeight); 17356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 17456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight); 17556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 17656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 17756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana/////////////////////////////////////////////////////////////////////////////// 17856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana// State management 17956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana/////////////////////////////////////////////////////////////////////////////// 18056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 18156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaint OpenGLRenderer::getSaveCount() const { 18256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return mSaveCount; 18356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 18456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 18556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaint OpenGLRenderer::save(int flags) { 18656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return saveSnapshot(); 18756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 18856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 18956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanavoid OpenGLRenderer::restore() { 19056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (mSaveCount == 0) return; 19156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 19256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (restoreSnapshot()) { 19356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana setScissorFromClip(); 19456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 19556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 19656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 19756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanavoid OpenGLRenderer::restoreToCount(int saveCount) { 19856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (saveCount <= 0 || saveCount > mSaveCount) return; 19956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 20056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana bool restoreClip = false; 20156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2026ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey while (mSaveCount != saveCount - 1) { 2036ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey restoreClip |= restoreSnapshot(); 2046ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey } 20556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 20656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (restoreClip) { 20756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana setScissorFromClip(); 20856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 20956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 21056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 21156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanaint OpenGLRenderer::saveSnapshot() { 21256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mSnapshot = new Snapshot(mSnapshot); 2136ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey return ++mSaveCount; 2146ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey} 21556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 21656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanabool OpenGLRenderer::restoreSnapshot() { 21756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; 2186ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer; 2196ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey bool restoreOrtho = mSnapshot->flags & Snapshot::kFlagDirtyOrtho; 2206ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 22156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana sp<Snapshot> current = mSnapshot; 22256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana sp<Snapshot> previous = mSnapshot->previous; 2236ab72d74b86e5f4ec3c3909366fd46c225a66bd7Jeff Sharkey 22456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (restoreOrtho) { 22556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mOrthoMatrix.load(current->orthoMatrix); 22656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 22756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 2289d0791bf6a047dbf7a99034130a5c4b437510fcfJeff Sharkey if (restoreLayer) { 2298a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock composeLayer(current, previous); 2308a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock } 2318a985d24ce9a38f40ed88fecbdcd0e75e3a68f44John Spurlock 23256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mSnapshot = previous; 23356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana mSaveCount--; 23456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 23556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return restoreClip; 23656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana} 23756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 23856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintanavoid OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { 23956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana if (!current->layer) { 24056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana LOGE("Attempting to compose a layer that does not exist"); 24156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana return; 24256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana } 24356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 24456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // Unbind current FBO and restore previous one 24556285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // Most of the time, previous->fbo will be 0 to bind the default buffer 24656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); 24756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 24856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // Restore the clip from the previous snapshot 24956285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana const Rect& clip = previous->clipRect; 25056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight()); 25156285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 25256285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana Layer* layer = current->layer; 25356285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 25456285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // Compute the correct texture coordinates for the FBO texture 25550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn // The texture is currently as big as the window but drawn with 25656285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana // a quad of the appropriate size 25756285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana const Rect& rect = layer->layer; 25856285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana 25950cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn drawTextureRect(rect.left, rect.top, rect.right, rect.bottom, 26056285a60e83138bb4b4f2d3bdec91b2f3ca11aa2Fred Quintana layer->texture, layer->alpha, layer->mode, layer->blend); 261603073430bbcb1bd29db7afb9b14e2732ad589fbFred Quintana 2621a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen LayerSize size(rect.getWidth(), rect.getHeight()); 263 // Failing to add the layer to the cache should happen only if the 264 // layer is too large 265 if (!mLayerCache.put(size, layer)) { 266 LAYER_LOGD("Deleting layer"); 267 268 glDeleteFramebuffers(1, &layer->fbo); 269 glDeleteTextures(1, &layer->texture); 270 271 delete layer; 272 } 273} 274 275/////////////////////////////////////////////////////////////////////////////// 276// Layers 277/////////////////////////////////////////////////////////////////////////////// 278 279int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, 280 const SkPaint* p, int flags) { 281 int count = saveSnapshot(); 282 283 int alpha = 255; 284 SkXfermode::Mode mode; 285 286 if (p) { 287 alpha = p->getAlpha(); 288 const bool isMode = SkXfermode::IsMode(p->getXfermode(), &mode); 289 if (!isMode) { 290 // Assume SRC_OVER 291 mode = SkXfermode::kSrcOver_Mode; 292 } 293 } else { 294 mode = SkXfermode::kSrcOver_Mode; 295 } 296 297 createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags); 298 299 return count; 300} 301 302int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom, 303 int alpha, int flags) { 304 int count = saveSnapshot(); 305 createLayer(mSnapshot, left, top, right, bottom, alpha, SkXfermode::kSrcOver_Mode, flags); 306 return count; 307} 308 309bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, 310 float right, float bottom, int alpha, SkXfermode::Mode mode,int flags) { 311 312 LAYER_LOGD("Requesting layer %fx%f", right - left, bottom - top); 313 LAYER_LOGD("Layer cache size = %d", mLayerCache.getSize()); 314 315 GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0; 316 LayerSize size(right - left, bottom - top); 317 318 Layer* layer = mLayerCache.get(size, previousFbo); 319 if (!layer) { 320 return false; 321 } 322 323 glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo); 324 325 // Clear the FBO 326 glDisable(GL_SCISSOR_TEST); 327 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 328 glClear(GL_COLOR_BUFFER_BIT); 329 glEnable(GL_SCISSOR_TEST); 330 331 // Save the layer in the snapshot 332 snapshot->flags |= Snapshot::kFlagIsLayer; 333 layer->mode = mode; 334 layer->alpha = alpha / 255.0f; 335 layer->layer.set(left, top, right, bottom); 336 337 snapshot->layer = layer; 338 snapshot->fbo = layer->fbo; 339 340 // Creates a new snapshot to draw into the FBO 341 saveSnapshot(); 342 // TODO: This doesn't preserve other transformations (check Skia first) 343 mSnapshot->transform.loadTranslate(-left, -top, 0.0f); 344 mSnapshot->setClip(0.0f, 0.0f, right - left, bottom - top); 345 mSnapshot->height = bottom - top; 346 setScissorFromClip(); 347 348 mSnapshot->flags = Snapshot::kFlagDirtyOrtho | Snapshot::kFlagClipSet; 349 mSnapshot->orthoMatrix.load(mOrthoMatrix); 350 351 // Change the ortho projection 352 mOrthoMatrix.loadOrtho(0.0f, right - left, bottom - top, 0.0f, 0.0f, 1.0f); 353 354 return true; 355} 356 357/////////////////////////////////////////////////////////////////////////////// 358// Transforms 359/////////////////////////////////////////////////////////////////////////////// 360 361void OpenGLRenderer::translate(float dx, float dy) { 362 mSnapshot->transform.translate(dx, dy, 0.0f); 363} 364 365void OpenGLRenderer::rotate(float degrees) { 366 mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); 367} 368 369void OpenGLRenderer::scale(float sx, float sy) { 370 mSnapshot->transform.scale(sx, sy, 1.0f); 371} 372 373void OpenGLRenderer::setMatrix(SkMatrix* matrix) { 374 mSnapshot->transform.load(*matrix); 375} 376 377void OpenGLRenderer::getMatrix(SkMatrix* matrix) { 378 mSnapshot->transform.copyTo(*matrix); 379} 380 381void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { 382 mat4 m(*matrix); 383 mSnapshot->transform.multiply(m); 384} 385 386/////////////////////////////////////////////////////////////////////////////// 387// Clipping 388/////////////////////////////////////////////////////////////////////////////// 389 390void OpenGLRenderer::setScissorFromClip() { 391 const Rect& clip = mSnapshot->clipRect; 392 glScissor(clip.left, mSnapshot->height - clip.bottom, clip.getWidth(), clip.getHeight()); 393} 394 395const Rect& OpenGLRenderer::getClipBounds() { 396 return mSnapshot->getLocalClip(); 397} 398 399bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { 400 Rect r(left, top, right, bottom); 401 mSnapshot->transform.mapRect(r); 402 return !mSnapshot->clipRect.intersects(r); 403} 404 405bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 406 bool clipped = mSnapshot->clip(left, top, right, bottom, op); 407 if (clipped) { 408 setScissorFromClip(); 409 } 410 return !mSnapshot->clipRect.isEmpty(); 411} 412 413/////////////////////////////////////////////////////////////////////////////// 414// Drawing 415/////////////////////////////////////////////////////////////////////////////// 416 417void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint) { 418 const float right = left + bitmap->width(); 419 const float bottom = top + bitmap->height(); 420 421 if (quickReject(left, top, right, bottom)) { 422 return; 423 } 424 425 const Texture* texture = mTextureCache.get(bitmap); 426 drawTextureRect(left, top, right, bottom, texture, paint); 427} 428 429void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint) { 430 Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height()); 431 const mat4 transform(*matrix); 432 transform.mapRect(r); 433 434 if (quickReject(r.left, r.top, r.right, r.bottom)) { 435 return; 436 } 437 438 const Texture* texture = mTextureCache.get(bitmap); 439 drawTextureRect(r.left, r.top, r.right, r.bottom, texture, paint); 440} 441 442void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, 443 float srcLeft, float srcTop, float srcRight, float srcBottom, 444 float dstLeft, float dstTop, float dstRight, float dstBottom, 445 const SkPaint* paint) { 446 if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) { 447 return; 448 } 449 450 const Texture* texture = mTextureCache.get(bitmap); 451 452 const float width = texture->width; 453 const float height = texture->height; 454 455 const float u1 = srcLeft / width; 456 const float v1 = srcTop / height; 457 const float u2 = srcRight / width; 458 const float v2 = srcBottom / height; 459 460 resetDrawTextureTexCoords(u1, v1, u2, v2); 461 462 drawTextureRect(dstLeft, dstTop, dstRight, dstBottom, texture, paint); 463 464 resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); 465} 466 467void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, 468 float left, float top, float right, float bottom, const SkPaint* paint) { 469 if (quickReject(left, top, right, bottom)) { 470 return; 471 } 472 473 const Texture* texture = mTextureCache.get(bitmap); 474 475 int alpha; 476 SkXfermode::Mode mode; 477 getAlphaAndMode(paint, &alpha, &mode); 478 479 Patch* mesh = mPatchCache.get(patch); 480 mesh->updateVertices(bitmap, left, top, right, bottom, 481 &patch->xDivs[0], &patch->yDivs[0], patch->numXDivs, patch->numYDivs); 482 483 // Specify right and bottom as +1.0f from left/top to prevent scaling since the 484 // patch mesh already defines the final size 485 drawTextureMesh(left, top, left + 1.0f, top + 1.0f, texture->id, alpha / 255.0f, 486 mode, texture->blend, &mesh->vertices[0].position[0], 487 &mesh->vertices[0].texture[0], mesh->indices, mesh->indicesCount); 488} 489 490void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 491 const Rect& clip = mSnapshot->clipRect; 492 drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true); 493} 494 495void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { 496 if (quickReject(left, top, right, bottom)) { 497 return; 498 } 499 500 SkXfermode::Mode mode; 501 502 const bool isMode = SkXfermode::IsMode(p->getXfermode(), &mode); 503 if (!isMode) { 504 // Assume SRC_OVER 505 mode = SkXfermode::kSrcOver_Mode; 506 } 507 508 // Skia draws using the color's alpha channel if < 255 509 // Otherwise, it uses the paint's alpha 510 int color = p->getColor(); 511 if (((color >> 24) & 0xff) == 255) { 512 color |= p->getAlpha() << 24; 513 } 514 515 drawColorRect(left, top, right, bottom, color, mode); 516} 517 518/////////////////////////////////////////////////////////////////////////////// 519// Shaders 520/////////////////////////////////////////////////////////////////////////////// 521 522void OpenGLRenderer::resetShader() { 523 mShader = OpenGLRenderer::kShaderNone; 524 mShaderBlend = false; 525 mShaderTileX = SkShader::kClamp_TileMode; 526 mShaderTileY = SkShader::kClamp_TileMode; 527} 528 529void OpenGLRenderer::setupBitmapShader(SkBitmap* bitmap, SkShader::TileMode tileX, 530 SkShader::TileMode tileY, SkMatrix* matrix, bool hasAlpha) { 531 mShader = OpenGLRenderer::kShaderBitmap; 532 mShaderBlend = hasAlpha; 533 mShaderBitmap = bitmap; 534 mShaderTileX = tileX; 535 mShaderTileY = tileY; 536 mShaderMatrix = matrix; 537} 538 539void OpenGLRenderer::setupLinearGradientShader(float* bounds, uint32_t* colors, 540 float* positions, SkShader::TileMode tileMode, SkMatrix* matrix, bool hasAlpha) { 541 mShader = OpenGLRenderer::kShaderLinearGradient; 542 mShaderBlend = hasAlpha; 543 mShaderTileX = tileMode; 544 mShaderTileY = tileMode; 545 mShaderMatrix = matrix; 546 mShaderBounds = bounds; 547 mShaderColors = colors; 548 mShaderPositions = positions; 549} 550 551/////////////////////////////////////////////////////////////////////////////// 552// Drawing implementation 553/////////////////////////////////////////////////////////////////////////////// 554 555void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, 556 int color, SkXfermode::Mode mode, bool ignoreTransform) { 557 // If a shader is set, preserve only the alpha 558 if (mShader != kShaderNone) { 559 color |= 0x00ffffff; 560 } 561 562 // Render using pre-multiplied alpha 563 const int alpha = (color >> 24) & 0xFF; 564 const GLfloat a = alpha / 255.0f; 565 const GLfloat r = a * ((color >> 16) & 0xFF) / 255.0f; 566 const GLfloat g = a * ((color >> 8) & 0xFF) / 255.0f; 567 const GLfloat b = a * ((color ) & 0xFF) / 255.0f; 568 569 switch (mShader) { 570 case OpenGLRenderer::kShaderBitmap: 571 drawBitmapShader(left, top, right, bottom, a, mode); 572 return; 573 case OpenGLRenderer::kShaderLinearGradient: 574 // TODO: Generate gradient texture, set appropriate shader 575 break; 576 default: 577 break; 578 } 579 580 // Pre-multiplication happens when setting the shader color 581 chooseBlending(alpha < 255 || mShaderBlend, mode); 582 583 mModelView.loadTranslate(left, top, 0.0f); 584 mModelView.scale(right - left, bottom - top, 1.0f); 585 586 if (!useProgram(mDrawColorProgram)) { 587 const GLvoid* p = &gDrawColorVertices[0].position[0]; 588 glVertexAttribPointer(mDrawColorProgram->position, 2, GL_FLOAT, GL_FALSE, 589 gDrawColorVertexStride, p); 590 } 591 592 if (!ignoreTransform) { 593 mDrawColorProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); 594 } else { 595 mat4 identity; 596 mDrawColorProgram->set(mOrthoMatrix, mModelView, identity); 597 } 598 599 glUniform4f(mDrawColorProgram->color, r, g, b, a); 600 601 glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount); 602} 603 604void OpenGLRenderer::drawBitmapShader(float left, float top, float right, float bottom, 605 float alpha, SkXfermode::Mode mode) { 606 const Texture* texture = mTextureCache.get(mShaderBitmap); 607 608 const float width = texture->width; 609 const float height = texture->height; 610 611 // This could be done in the vertex shader but we have only 4 vertices 612 float u1 = 0.0f; 613 float v1 = 0.0f; 614 float u2 = right - left; 615 float v2 = bottom - top; 616 617 if (mShaderMatrix) { 618 SkMatrix inverse; 619 mShaderMatrix->invert(&inverse); 620 mat4 m(inverse); 621 Rect r(u1, v1, u2, v2); 622 m.mapRect(r); 623 624 u1 = r.left; 625 u2 = r.right; 626 v1 = r.top; 627 v2 = r.bottom; 628 } 629 630 u1 /= width; 631 u2 /= width; 632 v1 /= height; 633 v2 /= height; 634 635 resetDrawTextureTexCoords(u1, v1, u2, v2); 636 637 drawTextureMesh(left, top, right, bottom, texture->id, alpha, mode, texture->blend, 638 &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL); 639 640 resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); 641} 642 643void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, 644 const Texture* texture, const SkPaint* paint) { 645 int alpha; 646 SkXfermode::Mode mode; 647 getAlphaAndMode(paint, &alpha, &mode); 648 649 drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, 650 &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL); 651} 652 653void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, 654 GLuint texture, float alpha, SkXfermode::Mode mode, bool blend) { 655 drawTextureMesh(left, top, right, bottom, texture, alpha, mode, blend, 656 &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL); 657} 658 659void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom, 660 GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, 661 GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount) { 662 mModelView.loadTranslate(left, top, 0.0f); 663 mModelView.scale(right - left, bottom - top, 1.0f); 664 665 useProgram(mDrawTextureProgram); 666 mDrawTextureProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); 667 668 chooseBlending(blend || alpha < 1.0f, mode); 669 670 if (texture != mLastTexture) { 671 glBindTexture(GL_TEXTURE_2D, texture); 672 mLastTexture = texture; 673 } 674 // TODO: Don't set the texture parameters every time 675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gTileModes[mShaderTileX]); 676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gTileModes[mShaderTileY]); 677 678 // Always premultiplied 679 glUniform4f(mDrawTextureProgram->color, alpha, alpha, alpha, alpha); 680 681 glVertexAttribPointer(mDrawTextureProgram->position, 2, GL_FLOAT, GL_FALSE, 682 gDrawTextureVertexStride, vertices); 683 glVertexAttribPointer(mDrawTextureProgram->texCoords, 2, GL_FLOAT, GL_FALSE, 684 gDrawTextureVertexStride, texCoords); 685 686 if (!indices) { 687 glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount); 688 } else { 689 glDrawElements(GL_TRIANGLES, elementsCount, GL_UNSIGNED_SHORT, indices); 690 } 691} 692 693void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied) { 694 // In theory we should not blend if the mode is Src, but it's rare enough 695 // that it's not worth it 696 blend = blend || mode != SkXfermode::kSrcOver_Mode; 697 if (blend) { 698 if (!mBlend) { 699 glEnable(GL_BLEND); 700 } 701 702 GLenum sourceMode = gBlends[mode].src; 703 GLenum destMode = gBlends[mode].dst; 704 if (!isPremultiplied && sourceMode == GL_ONE) { 705 sourceMode = GL_SRC_ALPHA; 706 } 707 708 if (sourceMode != mLastSrcMode || destMode != mLastDstMode) { 709 glBlendFunc(sourceMode, destMode); 710 mLastSrcMode = sourceMode; 711 mLastDstMode = destMode; 712 } 713 } else if (mBlend) { 714 glDisable(GL_BLEND); 715 } 716 mBlend = blend; 717} 718 719bool OpenGLRenderer::useProgram(const sp<Program>& program) { 720 if (!program->isInUse()) { 721 mCurrentProgram->remove(); 722 program->use(); 723 mCurrentProgram = program; 724 return false; 725 } 726 return true; 727} 728 729void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) { 730 TextureVertex* v = &mDrawTextureVertices[0]; 731 TextureVertex::setUV(v++, u1, v1); 732 TextureVertex::setUV(v++, u2, v1); 733 TextureVertex::setUV(v++, u1, v2); 734 TextureVertex::setUV(v++, u2, v2); 735} 736 737void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) { 738 if (paint) { 739 const bool isMode = SkXfermode::IsMode(paint->getXfermode(), mode); 740 if (!isMode) { 741 // Assume SRC_OVER 742 *mode = SkXfermode::kSrcOver_Mode; 743 } 744 745 // Skia draws using the color's alpha channel if < 255 746 // Otherwise, it uses the paint's alpha 747 int color = paint->getColor(); 748 *alpha = (color >> 24) & 0xFF; 749 if (*alpha == 255) { 750 *alpha = paint->getAlpha(); 751 } 752 } else { 753 *mode = SkXfermode::kSrcOver_Mode; 754 *alpha = 255; 755 } 756} 757 758}; // namespace uirenderer 759}; // namespace android 760