1118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian/* 2118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * Copyright (C) 2011 The Android Open Source Project 3118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * 4118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * you may not use this file except in compliance with the License. 6118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * You may obtain a copy of the License at 7118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * 8118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * 10118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * Unless required by applicable law or agreed to in writing, software 11118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * See the License for the specific language governing permissions and 14118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian * limitations under the License. 15118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian */ 16118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 17118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include <stdlib.h> 18118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include <stdint.h> 19118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include <sys/types.h> 20118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 21d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian#include <GLES/gl.h> 22d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian#include <GLES/glext.h> 23d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian 24118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include <utils/Errors.h> 25118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include <utils/Log.h> 26118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 27118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include <ui/GraphicBuffer.h> 28118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 29118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h" 30118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "SurfaceFlinger.h" 310f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 32118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 334a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian 34118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopiannamespace android { 35118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian// --------------------------------------------------------------------------- 36118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 373ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianLayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, 38118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const sp<Client>& client) 393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : LayerBaseClient(flinger, client), 40dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis mTextureName(0), mFlinger(flinger), mIsSecure(false) 41118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 42118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 43118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 44118d0245ee0a3b107055782aa8b555404b6f0280Mathias AgopianLayerScreenshot::~LayerScreenshot() 45118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 46118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian if (mTextureName) { 47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mFlinger->deleteTextureAsync(mTextureName); 48118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } 49118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 50118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 513ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianstatus_t LayerScreenshot::captureLocked(int32_t layerStack) { 524a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian GLfloat u, v; 533ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian status_t result = mFlinger->renderScreenToTextureLocked(layerStack, 543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian &mTextureName, &u, &v); 554a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian if (result != NO_ERROR) { 564a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian return result; 574a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian } 584a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian initTexture(u, v); 59dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 60dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // Currently screenshot always comes from the default display 61dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible(); 62dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 634a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian return NO_ERROR; 644a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian} 654a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian 66118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t LayerScreenshot::capture() { 67118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian GLfloat u, v; 68118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v); 69118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian if (result != NO_ERROR) { 70118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian return result; 71118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } 724a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian initTexture(u, v); 73dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 74dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // Currently screenshot always comes from the default display 75dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible(); 76dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 774a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian return NO_ERROR; 784a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian} 79118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 804a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopianvoid LayerScreenshot::initTexture(GLfloat u, GLfloat v) { 81118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glBindTexture(GL_TEXTURE_2D, mTextureName); 82118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 83118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 84118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mTexCoords[0] = 0; mTexCoords[1] = v; 85118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mTexCoords[2] = 0; mTexCoords[3] = 0; 86118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mTexCoords[4] = u; mTexCoords[5] = 0; 87118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian mTexCoords[6] = u; mTexCoords[7] = v; 884a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian} 89118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 904a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopianvoid LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) { 914a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian LayerBaseClient::initStates(w, h, flags); 923165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian if (!(flags & ISurfaceComposerClient::eHidden)) { 934a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian capture(); 944a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian } 95dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (flags & ISurfaceComposerClient::eSecure) { 96dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis ALOGW("ignoring surface flag eSecure - LayerScreenshot is considered " 97dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis "secure iff it captures the contents of a secure surface."); 98dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis } 994a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian} 1004a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian 1014a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopianuint32_t LayerScreenshot::doTransaction(uint32_t flags) 1024a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian{ 103921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const LayerBase::State& draw(drawingState()); 104921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const LayerBase::State& curr(currentState()); 1054a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian 1063165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian if (draw.flags & layer_state_t::eLayerHidden) { 1073165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian if (!(curr.flags & layer_state_t::eLayerHidden)) { 1084a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian // we're going from hidden to visible 1093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian status_t err = captureLocked(curr.layerStack); 1104a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian if (err != NO_ERROR) { 11132397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("createScreenshotSurface failed (%s)", strerror(-err)); 1124a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian } 1134a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian } 1143165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian } else if (curr.flags & layer_state_t::eLayerHidden) { 1154a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian // we're going from visible to hidden 1164a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian if (mTextureName) { 1174a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian glDeleteTextures(1, &mTextureName); 1184a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian mTextureName = 0; 1194a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian } 1204a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian } 1214a9ac37fe26644bb5253d15eec08be2edb896642Mathias Agopian return LayerBaseClient::doTransaction(flags); 122118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 123118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 125118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{ 126118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const State& s(drawingState()); 127f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian if (s.alpha>0) { 128118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian const GLfloat alpha = s.alpha/255.0f; 1294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const uint32_t fbHeight = hw->getHeight(); 130118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 131118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian if (s.alpha == 0xFF) { 132118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glDisable(GL_BLEND); 133b763d5fffa2f942a6ae3637fab17439dd32dbebcJesse Hall glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 134118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } else { 135118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glEnable(GL_BLEND); 136b763d5fffa2f942a6ae3637fab17439dd32dbebcJesse Hall glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 137b763d5fffa2f942a6ae3637fab17439dd32dbebcJesse Hall glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 138118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } 139118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 140dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis GLuint texName = mTextureName; 141dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis if (isSecure() && !hw->isSecure()) { 142dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis texName = mFlinger->getProtectedTexName(); 143dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis } 144dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 1454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian LayerMesh mesh; 1464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian computeGeometry(hw, &mesh); 1474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 148837d2f9e83e7d8625ef482d9c9d9afa852c8dbaaJesse Hall glColor4f(alpha, alpha, alpha, alpha); 149837d2f9e83e7d8625ef482d9c9d9afa852c8dbaaJesse Hall 150118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glDisable(GL_TEXTURE_EXTERNAL_OES); 151118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glEnable(GL_TEXTURE_2D); 152118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 153dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis glBindTexture(GL_TEXTURE_2D, texName); 154118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glMatrixMode(GL_TEXTURE); 155118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glLoadIdentity(); 156118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glMatrixMode(GL_MODELVIEW); 157118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 158118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 159118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords); 1604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); 1614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); 162118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 163118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glDisable(GL_BLEND); 164118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glDisable(GL_TEXTURE_2D); 165118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 166118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian } 167118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 168118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 169118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian// --------------------------------------------------------------------------- 170118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 171118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}; // namespace android 172