diff options
Diffstat (limited to 'services/surfaceflinger/LayerScreenshot.cpp')
-rw-r--r-- | services/surfaceflinger/LayerScreenshot.cpp | 71 |
1 files changed, 47 insertions, 24 deletions
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp index b42353c..f8009b3 100644 --- a/services/surfaceflinger/LayerScreenshot.cpp +++ b/services/surfaceflinger/LayerScreenshot.cpp @@ -18,6 +18,9 @@ #include <stdint.h> #include <sys/types.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + #include <utils/Errors.h> #include <utils/Log.h> @@ -25,34 +28,38 @@ #include "LayerScreenshot.h" #include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" +#include "DisplayDevice.h" namespace android { // --------------------------------------------------------------------------- -LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display, +LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client) - : LayerBaseClient(flinger, display, client), - mTextureName(0), mFlinger(flinger) + : LayerBaseClient(flinger, client), + mTextureName(0), mFlinger(flinger), mIsSecure(false) { } LayerScreenshot::~LayerScreenshot() { if (mTextureName) { - mFlinger->postMessageAsync( - new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); + mFlinger->deleteTextureAsync(mTextureName); } } -status_t LayerScreenshot::captureLocked() { +status_t LayerScreenshot::captureLocked(int32_t layerStack) { GLfloat u, v; - status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v); + status_t result = mFlinger->renderScreenToTextureLocked(layerStack, + &mTextureName, &u, &v); if (result != NO_ERROR) { return result; } initTexture(u, v); + + // Currently screenshot always comes from the default display + mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible(); + return NO_ERROR; } @@ -63,6 +70,10 @@ status_t LayerScreenshot::capture() { return result; } initTexture(u, v); + + // Currently screenshot always comes from the default display + mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible(); + return NO_ERROR; } @@ -78,25 +89,29 @@ void LayerScreenshot::initTexture(GLfloat u, GLfloat v) { void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) { LayerBaseClient::initStates(w, h, flags); - if (!(flags & ISurfaceComposer::eHidden)) { + if (!(flags & ISurfaceComposerClient::eHidden)) { capture(); } + if (flags & ISurfaceComposerClient::eSecure) { + ALOGW("ignoring surface flag eSecure - LayerScreenshot is considered " + "secure iff it captures the contents of a secure surface."); + } } uint32_t LayerScreenshot::doTransaction(uint32_t flags) { - const Layer::State& draw(drawingState()); - const Layer::State& curr(currentState()); + const LayerBase::State& draw(drawingState()); + const LayerBase::State& curr(currentState()); - if (draw.flags & ISurfaceComposer::eLayerHidden) { - if (!(curr.flags & ISurfaceComposer::eLayerHidden)) { + if (draw.flags & layer_state_t::eLayerHidden) { + if (!(curr.flags & layer_state_t::eLayerHidden)) { // we're going from hidden to visible - status_t err = captureLocked(); + status_t err = captureLocked(curr.layerStack); if (err != NO_ERROR) { ALOGW("createScreenshotSurface failed (%s)", strerror(-err)); } } - } else if (curr.flags & ISurfaceComposer::eLayerHidden) { + } else if (curr.flags & layer_state_t::eLayerHidden) { // we're going from visible to hidden if (mTextureName) { glDeleteTextures(1, &mTextureName); @@ -106,36 +121,44 @@ uint32_t LayerScreenshot::doTransaction(uint32_t flags) return LayerBaseClient::doTransaction(flags); } -void LayerScreenshot::onDraw(const Region& clip) const +void LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const { const State& s(drawingState()); if (s.alpha>0) { - const DisplayHardware& hw(graphicPlane(0).displayHardware()); const GLfloat alpha = s.alpha/255.0f; - const uint32_t fbHeight = hw.getHeight(); + const uint32_t fbHeight = hw->getHeight(); if (s.alpha == 0xFF) { glDisable(GL_BLEND); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } else { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + GLuint texName = mTextureName; + if (isSecure() && !hw->isSecure()) { + texName = mFlinger->getProtectedTexName(); } - glColor4f(0, 0, 0, alpha); + LayerMesh mesh; + computeGeometry(hw, &mesh); + + glColor4f(alpha, alpha, alpha, alpha); glDisable(GL_TEXTURE_EXTERNAL_OES); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, mTextureName); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glBindTexture(GL_TEXTURE_2D, texName); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords); - glVertexPointer(2, GL_FLOAT, 0, mVertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices); + glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); + glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); |