19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Errors.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/gl.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/glext.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian#include "clz.h" 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "BlurFilter.h" 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "LayerBlur.h" 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SurfaceFlinger.h" 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, 37593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian const sp<Client>& client) 38593c05ce7bcf7b6d94bd8c50da2b818cf05116b1Mathias Agopian : LayerBaseClient(flinger, display, client), mCacheDirty(true), 39d8b28e4fcddcacdbd2b69584a4e3aa12f52e8229Mathias Agopian mRefreshCache(true), mCacheAge(0), mTextureName(-1U), 40d8b28e4fcddcacdbd2b69584a4e3aa12f52e8229Mathias Agopian mWidthScale(1.0f), mHeightScale(1.0f), 41d8b28e4fcddcacdbd2b69584a4e3aa12f52e8229Mathias Agopian mBlurFormat(GGL_PIXEL_FORMAT_RGB_565) 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLayerBlur::~LayerBlur() 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTextureName != -1U) { 4881b0aa696ac954180caec6cb8cc1bb97440e03b5Mathias Agopian glDeleteTextures(1, &mTextureName); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid LayerBlur::setVisibleRegion(const Region& visibleRegion) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LayerBaseClient::setVisibleRegion(visibleRegion); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visibleRegionScreen.isEmpty()) { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTextureName != -1U) { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We're not visible, free the texture up. 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glBindTexture(GL_TEXTURE_2D, 0); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glDeleteTextures(1, &mTextureName); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextureName = -1U; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t LayerBlur::doTransaction(uint32_t flags) 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we're doing a transaction, refresh the cache! 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFlinger->isFrozen()) { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRefreshCache = true; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCacheDirty = true; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= eVisibleRegion; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this->contentDirty = true; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayerBase::doTransaction(flags); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion) 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this code-path must be as tight as possible, it's called each time 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the screen is composited. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (UNLIKELY(!visibleRegionScreen.isEmpty())) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if anything visible below us is invalidated, the cache becomes dirty 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mCacheDirty && 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCacheDirty = true; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCacheDirty) { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFlinger->isFrozen()) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update everything below us that is visible 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outDirtyRegion.orSelf(visibleRegionScreen); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nsecs_t now = systemTime(); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((now - mCacheAge) >= ms2ns(500)) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCacheAge = now; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRefreshCache = true; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCacheDirty = false; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAutoRefreshPending) { 98898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian mFlinger->postMessageAsync( 99898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian new MessageBase(MessageQueue::INVALIDATE), 100898c4c91be8e11b6d5388c623ae80f12ac25fd27Mathias Agopian ms2ns(500)); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAutoRefreshPending = true; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LayerBase::unlockPageFlip(planeTransform, outDirtyRegion); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid LayerBlur::onDraw(const Region& clip) const 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint32_t fbHeight = hw.getHeight(); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x = mTransformedBounds.left; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = mTransformedBounds.top; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int w = mTransformedBounds.width(); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int h = mTransformedBounds.height(); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GLint X = x; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GLint Y = fbHeight - (y + h); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (X < 0) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project w += X; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project X = 0; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Y < 0) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h += Y; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Y = 0; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (w<0 || h<0) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we're outside of the framebuffer 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTextureName == -1U) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create the texture name the first time 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // can't do that in the ctor, because it runs in another thread. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glGenTextures(1, &mTextureName); 1372c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat); 1382c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType); 1392c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) { 1402c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian mReadFormat = GL_RGBA; 1412c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian mReadType = GL_UNSIGNED_BYTE; 1422c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888; 1432c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1466158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian Region::const_iterator it = clip.begin(); 1476158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian Region::const_iterator const end = clip.end(); 1486158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian if (it != end) { 149e20a56d929fc8fedc2b468ea6d1900bd2aa6e81aMichael I. Gold#if defined(GL_OES_EGL_image_external) 150781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (GLExtensions::getInstance().haveTextureExternal()) { 151781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 152781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian } 153f8b4b4408cb864bf604608221eafa9d37323d348Mathias Agopian#endif 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glEnable(GL_TEXTURE_2D); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glBindTexture(GL_TEXTURE_2D, mTextureName); 1562c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRefreshCache) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRefreshCache = false; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAutoRefreshPending = false; 1602c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian 1612c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian int32_t pixelSize = 4; 1622c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian int32_t s = w; 1632c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian if (mReadType == GL_UNSIGNED_SHORT_5_6_5) { 1642c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian // allocate enough memory for 4-bytes (2 pixels) aligned data 1652c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian s = (w + 1) & ~1; 1662c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian pixelSize = 2; 1672c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian } 1682c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian 1692c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This reads the frame-buffer, so a h/w GL would have to 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // finish() its rendering first. we don't want to do that 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // too often. Read data is 4-bytes aligned. 1742c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels); 1752c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // blur that texture. 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GGLSurface bl; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bl.version = sizeof(GGLSurface); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bl.width = w; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bl.height = h; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bl.stride = s; 1822c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian bl.format = mBlurFormat; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bl.data = (GGLubyte*)pixels; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blurFilter(&bl, 8, 2); 185e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian 186781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian if (GLExtensions::getInstance().haveNpot()) { 1872c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0, 1882c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian mReadFormat, mReadType, pixels); 189e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian mWidthScale = 1.0f / w; 190e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian mHeightScale =-1.0f / h; 191e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian mYOffset = 0; 192e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian } else { 193e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian GLuint tw = 1 << (31 - clz(w)); 194e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian GLuint th = 1 << (31 - clz(h)); 1954961c959aebac31991fd7653853d47dfd79d3472Mathias Agopian if (tw < GLuint(w)) tw <<= 1; 1964961c959aebac31991fd7653853d47dfd79d3472Mathias Agopian if (th < GLuint(h)) th <<= 1; 1972c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0, 1982c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian mReadFormat, mReadType, NULL); 199e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 2002c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian mReadFormat, mReadType, pixels); 201e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian mWidthScale = 1.0f / tw; 202e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian mHeightScale =-1.0f / th; 203e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian mYOffset = th-h; 204e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free((void*)pixels); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2082c68dd0483dd4f7b211bea32652d42c3c7cd602cMathias Agopian 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const State& s = drawingState(); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (UNLIKELY(s.alpha < 0xFF)) { 211e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian const GLfloat alpha = s.alpha * (1.0f/255.0f); 212e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glColor4f(0, 0, 0, alpha); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glEnable(GL_BLEND); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glDisable(GL_BLEND); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 220e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian if (mFlags & DisplayHardware::SLOW_CONFIG) { 221e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian glDisable(GL_DITHER); 222e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian } else { 223e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian glEnable(GL_DITHER); 224e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian } 225e7c11d770ab44656d32330ba585489bd284b4a47Mathias Agopian 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 230e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glMatrixMode(GL_TEXTURE); 231e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glLoadIdentity(); 232e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glScalef(mWidthScale, mHeightScale, 1); 233e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glTranslatef(-x, mYOffset - y, 0); 234e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 235e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glVertexPointer(2, GL_FLOAT, 0, mVertices); 236e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, mVertices); 237e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian while (it != end) { 238e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian const Rect& r = *it++; 239e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian const GLint sy = fbHeight - (r.top + r.height()); 240e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glScissor(r.left, sy, r.width(), r.height()); 241e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 243e5c0a7b7810092a593ff386843927238c175bdbdMathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 244e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian glLoadIdentity(); 245e96aa3e859cb747e241dfa2999fcd142a688ed57Mathias Agopian glMatrixMode(GL_MODELVIEW); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 252