Home | History | Annotate | Download | only in surfaceflinger
      1 /*
      2  * Copyright (C) 2011 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 
     17 #include <stdlib.h>
     18 #include <stdint.h>
     19 #include <sys/types.h>
     20 
     21 #include <GLES/gl.h>
     22 #include <GLES/glext.h>
     23 
     24 #include <utils/Errors.h>
     25 #include <utils/Log.h>
     26 
     27 #include <ui/GraphicBuffer.h>
     28 
     29 #include "LayerScreenshot.h"
     30 #include "SurfaceFlinger.h"
     31 #include "DisplayDevice.h"
     32 
     33 
     34 namespace android {
     35 // ---------------------------------------------------------------------------
     36 
     37 LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
     38         const sp<Client>& client)
     39     : LayerBaseClient(flinger, client),
     40       mTextureName(0), mFlinger(flinger), mIsSecure(false)
     41 {
     42 }
     43 
     44 LayerScreenshot::~LayerScreenshot()
     45 {
     46     if (mTextureName) {
     47         mFlinger->deleteTextureAsync(mTextureName);
     48     }
     49 }
     50 
     51 status_t LayerScreenshot::captureLocked(int32_t layerStack) {
     52     GLfloat u, v;
     53     status_t result = mFlinger->renderScreenToTextureLocked(layerStack,
     54             &mTextureName, &u, &v);
     55     if (result != NO_ERROR) {
     56         return result;
     57     }
     58     initTexture(u, v);
     59 
     60     // Currently screenshot always comes from the default display
     61     mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
     62 
     63     return NO_ERROR;
     64 }
     65 
     66 status_t LayerScreenshot::capture() {
     67     GLfloat u, v;
     68     status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
     69     if (result != NO_ERROR) {
     70         return result;
     71     }
     72     initTexture(u, v);
     73 
     74     // Currently screenshot always comes from the default display
     75     mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
     76 
     77     return NO_ERROR;
     78 }
     79 
     80 void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
     81     glBindTexture(GL_TEXTURE_2D, mTextureName);
     82     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     83     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     84     mTexCoords[0] = 0;         mTexCoords[1] = v;
     85     mTexCoords[2] = 0;         mTexCoords[3] = 0;
     86     mTexCoords[4] = u;         mTexCoords[5] = 0;
     87     mTexCoords[6] = u;         mTexCoords[7] = v;
     88 }
     89 
     90 void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
     91     LayerBaseClient::initStates(w, h, flags);
     92     if (!(flags & ISurfaceComposerClient::eHidden)) {
     93         capture();
     94     }
     95     if (flags & ISurfaceComposerClient::eSecure) {
     96         ALOGW("ignoring surface flag eSecure - LayerScreenshot is considered "
     97                 "secure iff it captures the contents of a secure surface.");
     98     }
     99 }
    100 
    101 uint32_t LayerScreenshot::doTransaction(uint32_t flags)
    102 {
    103     const LayerBase::State& draw(drawingState());
    104     const LayerBase::State& curr(currentState());
    105 
    106     if (draw.flags & layer_state_t::eLayerHidden) {
    107         if (!(curr.flags & layer_state_t::eLayerHidden)) {
    108             // we're going from hidden to visible
    109             status_t err = captureLocked(curr.layerStack);
    110             if (err != NO_ERROR) {
    111                 ALOGW("createScreenshotSurface failed (%s)", strerror(-err));
    112             }
    113         }
    114     } else if (curr.flags & layer_state_t::eLayerHidden) {
    115         // we're going from visible to hidden
    116         if (mTextureName) {
    117             glDeleteTextures(1, &mTextureName);
    118             mTextureName = 0;
    119         }
    120     }
    121     return LayerBaseClient::doTransaction(flags);
    122 }
    123 
    124 void LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
    125 {
    126     const State& s(drawingState());
    127     if (s.alpha>0) {
    128         const GLfloat alpha = s.alpha/255.0f;
    129         const uint32_t fbHeight = hw->getHeight();
    130 
    131         if (s.alpha == 0xFF) {
    132             glDisable(GL_BLEND);
    133             glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    134         } else {
    135             glEnable(GL_BLEND);
    136             glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    137             glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    138         }
    139 
    140         GLuint texName = mTextureName;
    141         if (isSecure() && !hw->isSecure()) {
    142             texName = mFlinger->getProtectedTexName();
    143         }
    144 
    145         LayerMesh mesh;
    146         computeGeometry(hw, &mesh);
    147 
    148         glColor4f(alpha, alpha, alpha, alpha);
    149 
    150         glDisable(GL_TEXTURE_EXTERNAL_OES);
    151         glEnable(GL_TEXTURE_2D);
    152 
    153         glBindTexture(GL_TEXTURE_2D, texName);
    154         glMatrixMode(GL_TEXTURE);
    155         glLoadIdentity();
    156         glMatrixMode(GL_MODELVIEW);
    157 
    158         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    159         glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
    160         glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
    161         glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
    162 
    163         glDisable(GL_BLEND);
    164         glDisable(GL_TEXTURE_2D);
    165         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    166     }
    167 }
    168 
    169 // ---------------------------------------------------------------------------
    170 
    171 }; // namespace android
    172