*/
public static final int FX_SURFACE_DIM = 0x00020000;
- /** @hide */
- public static final int FX_SURFACE_SCREENSHOT = 0x00030000;
-
/** Mask used for FX values above @hide */
public static final int FX_SURFACE_MASK = 0x000F0000;
eFXSurfaceNormal = 0x00000000,
eFXSurfaceBlur = 0x00010000,
eFXSurfaceDim = 0x00020000,
- eFXSurfaceScreenshot= 0x00030000,
eFXSurfaceMask = 0x000F0000,
};
boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
mContext = context;
+ Bitmap screenshot = Surface.screenshot(0, 0);
+
+ if (screenshot == null) {
+ // Device is not capable of screenshots... we can't do an animation.
+ return;
+ }
+
// Screenshot does NOT include rotation!
mSnapshotRotation = 0;
- if (originalRotation == Surface.ROTATION_90
- || originalRotation == Surface.ROTATION_270) {
- mWidth = originalHeight;
- mHeight = originalWidth;
- } else {
- mWidth = originalWidth;
- mHeight = originalHeight;
- }
+ mWidth = screenshot.getWidth();
+ mHeight = screenshot.getHeight();
mOriginalRotation = originalRotation;
mOriginalWidth = originalWidth;
try {
try {
mSurface = new Surface(session, 0, "FreezeSurface",
- -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT);
- if (mSurface == null || !mSurface.isValid()) {
- // Screenshot failed, punt.
- mSurface = null;
- return;
- }
+ -1, mWidth, mHeight, PixelFormat.OPAQUE, 0);
mSurface.setLayer(FREEZE_LAYER + 1);
} catch (Surface.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);
" FREEZE " + mSurface + ": CREATE");
setRotation(originalRotation);
+
+ if (mSurface != null) {
+ Rect dirty = new Rect(0, 0, mWidth, mHeight);
+ Canvas c = null;
+ try {
+ c = mSurface.lockCanvas(dirty);
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Unable to lock surface", e);
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.w(TAG, "Unable to lock surface", e);
+ }
+ if (c == null) {
+ Slog.w(TAG, "Null surface canvas");
+ mSurface.destroy();
+ mSurface = null;
+ return;
+ }
+
+ Paint paint = new Paint(0);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
+ c.drawBitmap(screenshot, 0, 0, paint);
+
+ mSurface.unlockCanvasAndPost(c);
+ }
} finally {
if (!inTransaction) {
Surface.closeTransaction();
if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
"<<< CLOSE TRANSACTION ScreenRotationAnimation");
}
+
+ screenshot.recycle();
}
}
Layer.cpp \
LayerBase.cpp \
LayerDim.cpp \
- LayerScreenshot.cpp \
DdmConnection.cpp \
DisplayHardware/DisplayHardware.cpp \
DisplayHardware/DisplayHardwareBase.cpp \
Layer::~Layer()
{
- mFlinger->postMessageAsync(
- new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
+ class MessageDestroyGLState : public MessageBase {
+ GLuint texture;
+ public:
+ MessageDestroyGLState(GLuint texture) : texture(texture) { }
+ virtual bool handler() {
+ glDeleteTextures(1, &texture);
+ return true;
+ }
+ };
+ mFlinger->postMessageAsync( new MessageDestroyGLState(mTextureName) );
}
void Layer::onFrameQueued() {
+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include "LayerScreenshot.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display,
- const sp<Client>& client)
- : LayerBaseClient(flinger, display, client),
- mTextureName(0), mFlinger(flinger)
-{
-}
-
-LayerScreenshot::~LayerScreenshot()
-{
- if (mTextureName) {
- mFlinger->postMessageAsync(
- new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) );
- }
-}
-
-status_t LayerScreenshot::capture() {
- GLfloat u, v;
- status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
- if (result != NO_ERROR) {
- return result;
- }
-
- glBindTexture(GL_TEXTURE_2D, mTextureName);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- mTexCoords[0] = 0; mTexCoords[1] = v;
- mTexCoords[2] = 0; mTexCoords[3] = 0;
- mTexCoords[4] = u; mTexCoords[5] = 0;
- mTexCoords[6] = u; mTexCoords[7] = v;
-
- return NO_ERROR;
-}
-
-void LayerScreenshot::onDraw(const Region& clip) const
-{
- const State& s(drawingState());
- Region::const_iterator it = clip.begin();
- Region::const_iterator const end = clip.end();
- if (s.alpha>0 && (it != end)) {
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const GLfloat alpha = s.alpha/255.0f;
- const uint32_t fbHeight = hw.getHeight();
- glDisable(GL_DITHER);
-
- if (s.alpha == 0xFF) {
- glDisable(GL_BLEND);
- } else {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- glColor4f(0, 0, 0, alpha);
-
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- }
-#endif
-
- glBindTexture(GL_TEXTURE_2D, mTextureName);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glEnable(GL_TEXTURE_2D);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
-
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
- glVertexPointer(2, GL_FLOAT, 0, mVertices);
-
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- }
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LAYER_SCREENSHOT_H
-#define ANDROID_LAYER_SCREENSHOT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "LayerBase.h"
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class LayerScreenshot : public LayerBaseClient
-{
- GLuint mTextureName;
- GLfloat mTexCoords[8];
- sp<SurfaceFlinger> mFlinger;
-public:
- LayerScreenshot(SurfaceFlinger* flinger, DisplayID display,
- const sp<Client>& client);
- virtual ~LayerScreenshot();
-
- status_t capture();
-
- virtual void onDraw(const Region& clip) const;
- virtual bool isOpaque() const { return false; }
- virtual bool isSecure() const { return false; }
- virtual bool isProtectedByApp() const { return false; }
- virtual bool isProtectedByDRM() const { return false; }
- virtual const char* getTypeId() const { return "LayerScreenshot"; }
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_SCREENSHOT_H
#include "DdmConnection.h"
#include "Layer.h"
#include "LayerDim.h"
-#include "LayerScreenshot.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
case eFXSurfaceDim:
layer = createDimSurface(client, d, w, h, flags);
break;
- case eFXSurfaceScreenshot:
- layer = createScreenshotSurface(client, d, w, h, flags);
- break;
}
if (layer != 0) {
uint32_t w, uint32_t h, uint32_t flags)
{
sp<LayerDim> layer = new LayerDim(this, display, client);
- return layer;
-}
-
-sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
- const sp<Client>& client, DisplayID display,
- uint32_t w, uint32_t h, uint32_t flags)
-{
- sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
- status_t err = layer->capture();
- if (err != NO_ERROR) {
- layer.clear();
- LOGW("createScreenshotSurface failed (%s)", strerror(-err));
- }
+ layer->initStates(w, h, flags);
return layer;
}
// ---------------------------------------------------------------------------
-status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
- GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
-{
- Mutex::Autolock _l(mStateLock);
- return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
-}
-
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
{
status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
{
+ status_t result = PERMISSION_DENIED;
+
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
// get screen geometry
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t hw_w = hw.getWidth();
GLfloat u, v;
GLuint tname;
- status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
+ result = renderScreenToTextureLocked(0, &tname, &u, &v);
if (result != NO_ERROR) {
return result;
}
return result;
}
+ // back to main framebuffer
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ glDisable(GL_SCISSOR_TEST);
+
GLfloat vtx[8];
const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
glBindTexture(GL_TEXTURE_2D, tname);
class FreezeLock;
class Layer;
class LayerDim;
-class LayerScreenshot;
struct surface_flinger_cblk_t;
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
void screenReleased(DisplayID dpy);
void screenAcquired(DisplayID dpy);
- status_t renderScreenToTexture(DisplayID dpy,
- GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
-
- status_t postMessageAsync(const sp<MessageBase>& msg,
- nsecs_t reltime=0, uint32_t flags = 0);
-
- status_t postMessageSync(const sp<MessageBase>& msg,
- nsecs_t reltime=0, uint32_t flags = 0);
-
status_t removeLayer(const sp<LayerBase>& layer);
status_t addLayer(const sp<LayerBase>& layer);
status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
GLuint getProtectedTexName() const { return mProtectedTexName; }
-
- class MessageDestroyGLTexture : public MessageBase {
- GLuint texture;
- public:
- MessageDestroyGLTexture(GLuint texture) : texture(texture) { }
- virtual bool handler() {
- glDeleteTextures(1, &texture);
- return true;
- }
- };
-
-
private:
// DeathRecipient interface
virtual void binderDied(const wp<IBinder>& who);
friend class LayerBase;
friend class LayerBaseClient;
friend class Layer;
+ friend class LayerDim;
sp<ISurface> createSurface(
ISurfaceComposerClient::surface_data_t* params,
const sp<Client>& client, DisplayID display,
uint32_t w, uint32_t h, uint32_t flags);
- sp<LayerScreenshot> createScreenshotSurface(
- const sp<Client>& client, DisplayID display,
- uint32_t w, uint32_t h, uint32_t flags);
-
status_t removeSurface(const sp<Client>& client, SurfaceID sid);
status_t destroySurface(const wp<LayerBaseClient>& layer);
uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s);
mutable MessageQueue mEventQueue;
+ status_t postMessageAsync(const sp<MessageBase>& msg,
+ nsecs_t reltime=0, uint32_t flags = 0);
+
+ status_t postMessageSync(const sp<MessageBase>& msg,
+ nsecs_t reltime=0, uint32_t flags = 0);
+
// access must be protected by mStateLock
mutable Mutex mStateLock;
State mCurrentState;