Merge "rework screenshot API and implementation" into jb-mr2-dev
This commit is contained in:
commit
306f18c5fb
|
@ -103,7 +103,6 @@ public:
|
||||||
uint32_t reqWidth, uint32_t reqHeight,
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
|
uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
|
||||||
|
|
||||||
|
|
||||||
/* triggers screen off and waits for it to complete */
|
/* triggers screen off and waits for it to complete */
|
||||||
virtual void blank(const sp<IBinder>& display) = 0;
|
virtual void blank(const sp<IBinder>& display) = 0;
|
||||||
|
|
||||||
|
@ -113,6 +112,11 @@ public:
|
||||||
/* returns information about a display
|
/* returns information about a display
|
||||||
* intended to be used to get information about built-in displays */
|
* intended to be used to get information about built-in displays */
|
||||||
virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0;
|
virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0;
|
||||||
|
|
||||||
|
virtual status_t captureScreen(const sp<IBinder>& display,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -130,11 +134,12 @@ public:
|
||||||
GET_BUILT_IN_DISPLAY,
|
GET_BUILT_IN_DISPLAY,
|
||||||
SET_TRANSACTION_STATE,
|
SET_TRANSACTION_STATE,
|
||||||
AUTHENTICATE_SURFACE,
|
AUTHENTICATE_SURFACE,
|
||||||
CAPTURE_SCREEN,
|
CAPTURE_SCREEN_DEPRECATED,
|
||||||
BLANK,
|
BLANK,
|
||||||
UNBLANK,
|
UNBLANK,
|
||||||
GET_DISPLAY_INFO,
|
GET_DISPLAY_INFO,
|
||||||
CONNECT_DISPLAY,
|
CONNECT_DISPLAY,
|
||||||
|
CAPTURE_SCREEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
||||||
|
|
|
@ -156,10 +156,19 @@ private:
|
||||||
|
|
||||||
class ScreenshotClient
|
class ScreenshotClient
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
static status_t capture(
|
||||||
|
const sp<IBinder>& display,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ);
|
||||||
|
|
||||||
|
private:
|
||||||
sp<IMemoryHeap> mHeap;
|
sp<IMemoryHeap> mHeap;
|
||||||
uint32_t mWidth;
|
uint32_t mWidth;
|
||||||
uint32_t mHeight;
|
uint32_t mHeight;
|
||||||
PixelFormat mFormat;
|
PixelFormat mFormat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScreenshotClient();
|
ScreenshotClient();
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ public:
|
||||||
data.writeInt32(reqHeight);
|
data.writeInt32(reqHeight);
|
||||||
data.writeInt32(minLayerZ);
|
data.writeInt32(minLayerZ);
|
||||||
data.writeInt32(maxLayerZ);
|
data.writeInt32(maxLayerZ);
|
||||||
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
|
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_DEPRECATED, data, &reply);
|
||||||
*heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
|
*heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
|
||||||
*width = reply.readInt32();
|
*width = reply.readInt32();
|
||||||
*height = reply.readInt32();
|
*height = reply.readInt32();
|
||||||
|
@ -123,6 +123,23 @@ public:
|
||||||
return reply.readInt32();
|
return reply.readInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual status_t captureScreen(const sp<IBinder>& display,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ)
|
||||||
|
{
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
||||||
|
data.writeStrongBinder(display);
|
||||||
|
data.writeStrongBinder(producer->asBinder());
|
||||||
|
data.writeInt32(reqWidth);
|
||||||
|
data.writeInt32(reqHeight);
|
||||||
|
data.writeInt32(minLayerZ);
|
||||||
|
data.writeInt32(maxLayerZ);
|
||||||
|
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
|
||||||
|
return reply.readInt32();
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool authenticateSurfaceTexture(
|
virtual bool authenticateSurfaceTexture(
|
||||||
const sp<IGraphicBufferProducer>& bufferProducer) const
|
const sp<IGraphicBufferProducer>& bufferProducer) const
|
||||||
{
|
{
|
||||||
|
@ -268,7 +285,7 @@ status_t BnSurfaceComposer::onTransact(
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
bootFinished();
|
bootFinished();
|
||||||
} break;
|
} break;
|
||||||
case CAPTURE_SCREEN: {
|
case CAPTURE_SCREEN_DEPRECATED: {
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
sp<IBinder> display = data.readStrongBinder();
|
sp<IBinder> display = data.readStrongBinder();
|
||||||
uint32_t reqWidth = data.readInt32();
|
uint32_t reqWidth = data.readInt32();
|
||||||
|
@ -286,6 +303,19 @@ status_t BnSurfaceComposer::onTransact(
|
||||||
reply->writeInt32(f);
|
reply->writeInt32(f);
|
||||||
reply->writeInt32(res);
|
reply->writeInt32(res);
|
||||||
} break;
|
} break;
|
||||||
|
case CAPTURE_SCREEN: {
|
||||||
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
|
sp<IBinder> display = data.readStrongBinder();
|
||||||
|
sp<IGraphicBufferProducer> producer =
|
||||||
|
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
|
||||||
|
uint32_t reqWidth = data.readInt32();
|
||||||
|
uint32_t reqHeight = data.readInt32();
|
||||||
|
uint32_t minLayerZ = data.readInt32();
|
||||||
|
uint32_t maxLayerZ = data.readInt32();
|
||||||
|
status_t res = captureScreen(display, producer,
|
||||||
|
reqWidth, reqHeight, minLayerZ, maxLayerZ);
|
||||||
|
reply->writeInt32(res);
|
||||||
|
} break;
|
||||||
case AUTHENTICATE_SURFACE: {
|
case AUTHENTICATE_SURFACE: {
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
sp<IGraphicBufferProducer> bufferProducer =
|
sp<IGraphicBufferProducer> bufferProducer =
|
||||||
|
|
|
@ -606,6 +606,17 @@ void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
status_t ScreenshotClient::capture(
|
||||||
|
const sp<IBinder>& display,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ) {
|
||||||
|
sp<ISurfaceComposer> s(ComposerService::getComposerService());
|
||||||
|
if (s == NULL) return NO_INIT;
|
||||||
|
return s->captureScreen(display, producer,
|
||||||
|
reqWidth, reqHeight, minLayerZ, maxLayerZ);
|
||||||
|
}
|
||||||
|
|
||||||
ScreenshotClient::ScreenshotClient()
|
ScreenshotClient::ScreenshotClient()
|
||||||
: mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
|
: mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,10 @@ protected:
|
||||||
virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
|
virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
|
||||||
virtual void clearStats();
|
virtual void clearStats();
|
||||||
|
|
||||||
|
sp<SurfaceFlingerConsumer> getConsumer() const {
|
||||||
|
return mSurfaceFlingerConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Creates an instance of ISurface for this Layer.
|
// Creates an instance of ISurface for this Layer.
|
||||||
virtual sp<ISurface> createSurface();
|
virtual sp<ISurface> createSurface();
|
||||||
|
|
|
@ -18,152 +18,28 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <GLES/gl.h>
|
|
||||||
#include <GLES/glext.h>
|
|
||||||
|
|
||||||
#include <utils/Errors.h>
|
|
||||||
#include <utils/Log.h>
|
|
||||||
|
|
||||||
#include <ui/GraphicBuffer.h>
|
|
||||||
|
|
||||||
#include "LayerScreenshot.h"
|
#include "LayerScreenshot.h"
|
||||||
#include "SurfaceFlinger.h"
|
#include "SurfaceFlinger.h"
|
||||||
#include "DisplayDevice.h"
|
#include "DisplayDevice.h"
|
||||||
|
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
|
LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
|
||||||
const sp<Client>& client)
|
const sp<Client>& client)
|
||||||
: LayerBaseClient(flinger, client),
|
: Layer(flinger, client)
|
||||||
mTextureName(0), mFlinger(flinger), mIsSecure(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerScreenshot::~LayerScreenshot()
|
void LayerScreenshot::onFirstRef()
|
||||||
{
|
{
|
||||||
if (mTextureName) {
|
Layer::onFirstRef();
|
||||||
mFlinger->deleteTextureAsync(mTextureName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t LayerScreenshot::captureLocked(int32_t layerStack) {
|
// FIXME: we currently hardcode the default display
|
||||||
GLfloat u, v;
|
// it's unclear what should we do instead.
|
||||||
status_t result = mFlinger->renderScreenToTextureLocked(layerStack,
|
sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
|
||||||
&mTextureName, &u, &v);
|
mFlinger->captureScreenImplLocked(hw, getConsumer()->getBufferQueue(),
|
||||||
if (result != NO_ERROR) {
|
0, 0, 0, 0x7FFFFFFF);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
initTexture(u, v);
|
|
||||||
|
|
||||||
// Currently screenshot always comes from the default display
|
|
||||||
mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
|
|
||||||
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t LayerScreenshot::capture() {
|
|
||||||
GLfloat u, v;
|
|
||||||
status_t result = mFlinger->renderScreenToTexture(0, &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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
|
|
||||||
LayerBaseClient::initStates(w, h, flags);
|
|
||||||
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 LayerBase::State& draw(drawingState());
|
|
||||||
const LayerBase::State& curr(currentState());
|
|
||||||
|
|
||||||
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(curr.layerStack);
|
|
||||||
if (err != NO_ERROR) {
|
|
||||||
ALOGW("createScreenshotSurface failed (%s)", strerror(-err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (curr.flags & layer_state_t::eLayerHidden) {
|
|
||||||
// we're going from visible to hidden
|
|
||||||
if (mTextureName) {
|
|
||||||
glDeleteTextures(1, &mTextureName);
|
|
||||||
mTextureName = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return LayerBaseClient::doTransaction(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LayerScreenshot::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
|
|
||||||
{
|
|
||||||
const State& s(drawingState());
|
|
||||||
if (s.alpha>0) {
|
|
||||||
const GLfloat alpha = s.alpha/255.0f;
|
|
||||||
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_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();
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerMesh mesh;
|
|
||||||
computeGeometry(hw, &mesh);
|
|
||||||
|
|
||||||
glColor4f(alpha, alpha, alpha, alpha);
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
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, mesh.getVertices());
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -20,39 +20,18 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include "Layer.h"
|
||||||
#include <EGL/eglext.h>
|
|
||||||
|
|
||||||
#include "LayerBase.h"
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
class LayerScreenshot : public LayerBaseClient
|
class LayerScreenshot : public Layer
|
||||||
{
|
{
|
||||||
GLuint mTextureName;
|
|
||||||
GLfloat mTexCoords[8];
|
|
||||||
sp<SurfaceFlinger> mFlinger;
|
|
||||||
bool mIsSecure;
|
|
||||||
public:
|
public:
|
||||||
LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
|
LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
|
||||||
virtual ~LayerScreenshot();
|
protected:
|
||||||
|
virtual void onFirstRef();
|
||||||
status_t capture();
|
|
||||||
|
|
||||||
virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
|
|
||||||
virtual uint32_t doTransaction(uint32_t flags);
|
|
||||||
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
|
|
||||||
virtual bool isOpaque() const { return false; }
|
|
||||||
virtual bool isSecure() const { return mIsSecure; }
|
|
||||||
virtual bool isProtectedByApp() const { return false; }
|
|
||||||
virtual bool isProtectedByDRM() const { return false; }
|
|
||||||
virtual const char* getTypeId() const { return "LayerScreenshot"; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
status_t captureLocked(int32_t layerStack);
|
|
||||||
void initTexture(GLfloat u, GLfloat v);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -2020,6 +2020,7 @@ sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
|
||||||
uint32_t w, uint32_t h, uint32_t flags)
|
uint32_t w, uint32_t h, uint32_t flags)
|
||||||
{
|
{
|
||||||
sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
|
sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
|
||||||
|
layer->setBuffers(w, h, PIXEL_FORMAT_RGBA_8888, flags);
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2605,101 +2606,69 @@ void SurfaceFlinger::repaintEverything() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
// Capture screen into an IGraphiBufferProducer
|
||||||
status_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack,
|
|
||||||
GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
|
|
||||||
{
|
|
||||||
Mutex::Autolock _l(mStateLock);
|
|
||||||
return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack,
|
|
||||||
GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
|
|
||||||
{
|
|
||||||
ATRACE_CALL();
|
|
||||||
|
|
||||||
if (!GLExtensions::getInstance().haveFramebufferObject())
|
|
||||||
return INVALID_OPERATION;
|
|
||||||
|
|
||||||
// get screen geometry
|
|
||||||
// FIXME: figure out what it means to have a screenshot texture w/ multi-display
|
|
||||||
sp<const DisplayDevice> hw(getDefaultDisplayDevice());
|
|
||||||
const uint32_t hw_w = hw->getWidth();
|
|
||||||
const uint32_t hw_h = hw->getHeight();
|
|
||||||
GLfloat u = 1;
|
|
||||||
GLfloat v = 1;
|
|
||||||
|
|
||||||
// make sure to clear all GL error flags
|
|
||||||
while ( glGetError() != GL_NO_ERROR ) ;
|
|
||||||
|
|
||||||
// create a FBO
|
|
||||||
GLuint name, tname;
|
|
||||||
glGenTextures(1, &tname);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tname);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
|
|
||||||
hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
|
||||||
while ( glGetError() != GL_NO_ERROR ) ;
|
|
||||||
GLint tw = (2 << (31 - clz(hw_w)));
|
|
||||||
GLint th = (2 << (31 - clz(hw_h)));
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
|
|
||||||
tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
|
||||||
u = GLfloat(hw_w) / tw;
|
|
||||||
v = GLfloat(hw_h) / th;
|
|
||||||
}
|
|
||||||
glGenFramebuffersOES(1, &name);
|
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
|
|
||||||
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
|
|
||||||
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
|
|
||||||
|
|
||||||
DisplayDevice::setViewportAndProjection(hw);
|
|
||||||
|
|
||||||
// redraw the screen entirely...
|
|
||||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glClearColor(0,0,0,1);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
|
|
||||||
const size_t count = layers.size();
|
|
||||||
for (size_t i=0 ; i<count ; ++i) {
|
|
||||||
const sp<LayerBase>& layer(layers[i]);
|
|
||||||
layer->draw(hw);
|
|
||||||
}
|
|
||||||
|
|
||||||
hw->compositionComplete();
|
|
||||||
|
|
||||||
// back to main framebuffer
|
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
|
|
||||||
glDeleteFramebuffersOES(1, &name);
|
|
||||||
|
|
||||||
*textureName = tname;
|
|
||||||
*uOut = u;
|
|
||||||
*vOut = v;
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
status_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
|
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
|
||||||
sp<IMemoryHeap>* heap,
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
uint32_t* w, uint32_t* h, PixelFormat* f,
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
uint32_t sw, uint32_t sh,
|
uint32_t minLayerZ, uint32_t maxLayerZ) {
|
||||||
|
|
||||||
|
if (CC_UNLIKELY(display == 0))
|
||||||
|
return BAD_VALUE;
|
||||||
|
|
||||||
|
if (CC_UNLIKELY(producer == 0))
|
||||||
|
return BAD_VALUE;
|
||||||
|
|
||||||
|
class MessageCaptureScreen : public MessageBase {
|
||||||
|
SurfaceFlinger* flinger;
|
||||||
|
sp<IBinder> display;
|
||||||
|
sp<IGraphicBufferProducer> producer;
|
||||||
|
uint32_t reqWidth, reqHeight;
|
||||||
|
uint32_t minLayerZ,maxLayerZ;
|
||||||
|
status_t result;
|
||||||
|
public:
|
||||||
|
MessageCaptureScreen(SurfaceFlinger* flinger,
|
||||||
|
const sp<IBinder>& display,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ)
|
||||||
|
: flinger(flinger), display(display), producer(producer),
|
||||||
|
reqWidth(reqWidth), reqHeight(reqHeight),
|
||||||
|
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
|
||||||
|
result(PERMISSION_DENIED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
status_t getResult() const {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
virtual bool handler() {
|
||||||
|
Mutex::Autolock _l(flinger->mStateLock);
|
||||||
|
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
|
||||||
|
result = flinger->captureScreenImplLocked(hw, producer,
|
||||||
|
reqWidth, reqHeight, minLayerZ, maxLayerZ);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sp<MessageBase> msg = new MessageCaptureScreen(this,
|
||||||
|
display, producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
|
||||||
|
status_t res = postMessageSync(msg);
|
||||||
|
if (res == NO_ERROR) {
|
||||||
|
res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t SurfaceFlinger::captureScreenImplLocked(
|
||||||
|
const sp<const DisplayDevice>& hw,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
uint32_t minLayerZ, uint32_t maxLayerZ)
|
uint32_t minLayerZ, uint32_t maxLayerZ)
|
||||||
{
|
{
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
|
|
||||||
status_t result = PERMISSION_DENIED;
|
|
||||||
|
|
||||||
if (!GLExtensions::getInstance().haveFramebufferObject()) {
|
|
||||||
return INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get screen geometry
|
// get screen geometry
|
||||||
sp<const DisplayDevice> hw(getDisplayDevice(display));
|
|
||||||
const uint32_t hw_w = hw->getWidth();
|
const uint32_t hw_w = hw->getWidth();
|
||||||
const uint32_t hw_h = hw->getHeight();
|
const uint32_t hw_h = hw->getHeight();
|
||||||
|
|
||||||
|
@ -2709,68 +2678,128 @@ status_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
|
||||||
return PERMISSION_DENIED;
|
return PERMISSION_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sw > hw_w) || (sh > hw_h)) {
|
if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
|
||||||
ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
|
ALOGE("size mismatch (%d, %d) > (%d, %d)",
|
||||||
|
reqWidth, reqHeight, hw_w, hw_h);
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sw = (!sw) ? hw_w : sw;
|
reqWidth = (!reqWidth) ? hw_w : reqWidth;
|
||||||
sh = (!sh) ? hw_h : sh;
|
reqHeight = (!reqHeight) ? hw_h : reqHeight;
|
||||||
const size_t size = sw * sh * 4;
|
const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
|
||||||
const bool filtering = sw != hw_w || sh != hw_h;
|
|
||||||
|
|
||||||
// ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
|
// Create a surface to render into
|
||||||
// sw, sh, minLayerZ, maxLayerZ);
|
sp<Surface> surface = new Surface(producer);
|
||||||
|
ANativeWindow* const window = surface.get();
|
||||||
|
|
||||||
|
// set the buffer size to what the user requested
|
||||||
|
native_window_set_buffers_user_dimensions(window, reqWidth, reqHeight);
|
||||||
|
|
||||||
|
// and create the corresponding EGLSurface
|
||||||
|
EGLSurface eglSurface = eglCreateWindowSurface(
|
||||||
|
mEGLDisplay, mEGLConfig, window, NULL);
|
||||||
|
if (eglSurface == EGL_NO_SURFACE) {
|
||||||
|
ALOGE("captureScreenImplLocked: eglCreateWindowSurface() failed 0x%4x",
|
||||||
|
eglGetError());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext)) {
|
||||||
|
ALOGE("captureScreenImplLocked: eglMakeCurrent() failed 0x%4x",
|
||||||
|
eglGetError());
|
||||||
|
eglDestroySurface(mEGLDisplay, eglSurface);
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure to clear all GL error flags
|
// make sure to clear all GL error flags
|
||||||
while ( glGetError() != GL_NO_ERROR ) ;
|
while ( glGetError() != GL_NO_ERROR ) ;
|
||||||
|
|
||||||
// create a FBO
|
// set-up our viewport
|
||||||
GLuint name, tname;
|
glViewport(0, 0, reqWidth, reqHeight);
|
||||||
glGenRenderbuffersOES(1, &tname);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
|
glLoadIdentity();
|
||||||
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
|
glOrthof(0, hw_w, 0, hw_h, 0, 1);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
glGenFramebuffersOES(1, &name);
|
// redraw the screen entirely...
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
|
glDisable(GL_TEXTURE_2D);
|
||||||
GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
|
glClearColor(0,0,0,1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
|
const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
|
||||||
|
const size_t count = layers.size();
|
||||||
if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
|
for (size_t i=0 ; i<count ; ++i) {
|
||||||
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
// invert everything, b/c glReadPixel() below will invert the FB
|
const uint32_t z = layer->drawingState().z;
|
||||||
GLint viewport[4];
|
if (z >= minLayerZ && z <= maxLayerZ) {
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
if (filtering) layer->setFiltering(true);
|
||||||
glViewport(0, 0, sw, sh);
|
layer->draw(hw);
|
||||||
glMatrixMode(GL_PROJECTION);
|
if (filtering) layer->setFiltering(false);
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrthof(0, hw_w, hw_h, 0, 0, 1);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
|
|
||||||
// redraw the screen entirely...
|
|
||||||
glClearColor(0,0,0,1);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
|
|
||||||
const size_t count = layers.size();
|
|
||||||
for (size_t i=0 ; i<count ; ++i) {
|
|
||||||
const sp<LayerBase>& layer(layers[i]);
|
|
||||||
const uint32_t z = layer->drawingState().z;
|
|
||||||
if (z >= minLayerZ && z <= maxLayerZ) {
|
|
||||||
if (filtering) layer->setFiltering(true);
|
|
||||||
layer->draw(hw);
|
|
||||||
if (filtering) layer->setFiltering(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// and finishing things up...
|
||||||
|
if (eglSwapBuffers(mEGLDisplay, eglSurface) != EGL_TRUE) {
|
||||||
|
ALOGE("captureScreenImplLocked: eglSwapBuffers() failed 0x%4x",
|
||||||
|
eglGetError());
|
||||||
|
eglDestroySurface(mEGLDisplay, eglSurface);
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
eglDestroySurface(mEGLDisplay, eglSurface);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Capture screen into an IMemoryHeap (legacy)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
status_t SurfaceFlinger::captureScreenImplLocked(
|
||||||
|
const sp<const DisplayDevice>& hw,
|
||||||
|
sp<IMemoryHeap>* heap,
|
||||||
|
uint32_t* w, uint32_t* h, PixelFormat* f,
|
||||||
|
uint32_t sw, uint32_t sh,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ)
|
||||||
|
{
|
||||||
|
ATRACE_CALL();
|
||||||
|
|
||||||
|
if (!GLExtensions::getInstance().haveFramebufferObject()) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the texture that will receive the screenshot, later we'll
|
||||||
|
// attach a FBO to it so we can call glReadPixels().
|
||||||
|
GLuint tname;
|
||||||
|
glGenTextures(1, &tname);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tname);
|
||||||
|
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
// the GLConsumer will provide the BufferQueue
|
||||||
|
sp<GLConsumer> consumer = new GLConsumer(tname, true, GL_TEXTURE_2D);
|
||||||
|
consumer->getBufferQueue()->setDefaultBufferFormat(HAL_PIXEL_FORMAT_RGBA_8888);
|
||||||
|
|
||||||
|
// call the new screenshot taking code, passing a BufferQueue to it
|
||||||
|
status_t result = captureScreenImplLocked(hw,
|
||||||
|
consumer->getBufferQueue(), sw, sh, minLayerZ, maxLayerZ);
|
||||||
|
|
||||||
|
if (result == NO_ERROR) {
|
||||||
|
result = consumer->updateTexImage();
|
||||||
|
if (result == NO_ERROR) {
|
||||||
|
// create a FBO
|
||||||
|
GLuint name;
|
||||||
|
glGenFramebuffersOES(1, &name);
|
||||||
|
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
|
||||||
|
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
|
||||||
|
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
|
||||||
|
|
||||||
|
sp<GraphicBuffer> buf(consumer->getCurrentBuffer());
|
||||||
|
sw = buf->getWidth();
|
||||||
|
sh = buf->getHeight();
|
||||||
|
size_t size = buf->getStride() * sh * 4;
|
||||||
|
|
||||||
// check for errors and return screen capture
|
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
|
||||||
// error while rendering
|
|
||||||
result = INVALID_OPERATION;
|
|
||||||
} else {
|
|
||||||
// allocate shared memory large enough to hold the
|
// allocate shared memory large enough to hold the
|
||||||
// screen capture
|
// screen capture
|
||||||
sp<MemoryHeapBase> base(
|
sp<MemoryHeapBase> base(
|
||||||
|
@ -2790,59 +2819,48 @@ status_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display,
|
||||||
} else {
|
} else {
|
||||||
result = NO_MEMORY;
|
result = NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// back to main framebuffer
|
||||||
|
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
|
||||||
|
glDeleteFramebuffersOES(1, &name);
|
||||||
}
|
}
|
||||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPopMatrix();
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
} else {
|
|
||||||
result = BAD_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// release FBO resources
|
glDeleteTextures(1, &tname);
|
||||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
|
|
||||||
glDeleteRenderbuffersOES(1, &tname);
|
|
||||||
glDeleteFramebuffersOES(1, &name);
|
|
||||||
|
|
||||||
hw->compositionComplete();
|
|
||||||
|
|
||||||
// ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
|
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
|
||||||
sp<IMemoryHeap>* heap,
|
sp<IMemoryHeap>* heap,
|
||||||
uint32_t* width, uint32_t* height, PixelFormat* format,
|
uint32_t* outWidth, uint32_t* outHeight, PixelFormat* outFormat,
|
||||||
uint32_t sw, uint32_t sh,
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
uint32_t minLayerZ, uint32_t maxLayerZ)
|
uint32_t minLayerZ, uint32_t maxLayerZ)
|
||||||
{
|
{
|
||||||
if (CC_UNLIKELY(display == 0))
|
if (CC_UNLIKELY(display == 0))
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
|
|
||||||
if (!GLExtensions::getInstance().haveFramebufferObject())
|
|
||||||
return INVALID_OPERATION;
|
|
||||||
|
|
||||||
class MessageCaptureScreen : public MessageBase {
|
class MessageCaptureScreen : public MessageBase {
|
||||||
SurfaceFlinger* flinger;
|
SurfaceFlinger* flinger;
|
||||||
sp<IBinder> display;
|
sp<IBinder> display;
|
||||||
sp<IMemoryHeap>* heap;
|
sp<IMemoryHeap>* heap;
|
||||||
uint32_t* w;
|
uint32_t* outWidth;
|
||||||
uint32_t* h;
|
uint32_t* outHeight;
|
||||||
PixelFormat* f;
|
PixelFormat* outFormat;
|
||||||
uint32_t sw;
|
uint32_t reqWidth;
|
||||||
uint32_t sh;
|
uint32_t reqHeight;
|
||||||
uint32_t minLayerZ;
|
uint32_t minLayerZ;
|
||||||
uint32_t maxLayerZ;
|
uint32_t maxLayerZ;
|
||||||
status_t result;
|
status_t result;
|
||||||
public:
|
public:
|
||||||
MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display,
|
MessageCaptureScreen(SurfaceFlinger* flinger,
|
||||||
sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
|
const sp<IBinder>& display, sp<IMemoryHeap>* heap,
|
||||||
uint32_t sw, uint32_t sh,
|
uint32_t* outWidth, uint32_t* outHeight, PixelFormat* outFormat,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
uint32_t minLayerZ, uint32_t maxLayerZ)
|
uint32_t minLayerZ, uint32_t maxLayerZ)
|
||||||
: flinger(flinger), display(display),
|
: flinger(flinger), display(display), heap(heap),
|
||||||
heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
|
outWidth(outWidth), outHeight(outHeight), outFormat(outFormat),
|
||||||
|
reqWidth(reqWidth), reqHeight(reqHeight),
|
||||||
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
|
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
|
||||||
result(PERMISSION_DENIED)
|
result(PERMISSION_DENIED)
|
||||||
{
|
{
|
||||||
|
@ -2852,14 +2870,17 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
|
||||||
}
|
}
|
||||||
virtual bool handler() {
|
virtual bool handler() {
|
||||||
Mutex::Autolock _l(flinger->mStateLock);
|
Mutex::Autolock _l(flinger->mStateLock);
|
||||||
result = flinger->captureScreenImplLocked(display,
|
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
|
||||||
heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
|
result = flinger->captureScreenImplLocked(hw, heap,
|
||||||
|
outWidth, outHeight, outFormat,
|
||||||
|
reqWidth, reqHeight, minLayerZ, maxLayerZ);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sp<MessageBase> msg = new MessageCaptureScreen(this,
|
sp<MessageBase> msg = new MessageCaptureScreen(this, display, heap,
|
||||||
display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
|
outWidth, outHeight, outFormat,
|
||||||
|
reqWidth, reqHeight, minLayerZ, maxLayerZ);
|
||||||
status_t res = postMessageSync(msg);
|
status_t res = postMessageSync(msg);
|
||||||
if (res == NO_ERROR) {
|
if (res == NO_ERROR) {
|
||||||
res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
|
res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
|
||||||
|
|
|
@ -103,14 +103,6 @@ public:
|
||||||
// force full composition on all displays
|
// force full composition on all displays
|
||||||
void repaintEverything();
|
void repaintEverything();
|
||||||
|
|
||||||
// renders content on given display to a texture. thread-safe version.
|
|
||||||
status_t renderScreenToTexture(uint32_t layerStack, GLuint* textureName,
|
|
||||||
GLfloat* uOut, GLfloat* vOut);
|
|
||||||
|
|
||||||
// renders content on given display to a texture, w/o acquiring main lock
|
|
||||||
status_t renderScreenToTextureLocked(uint32_t layerStack, GLuint* textureName,
|
|
||||||
GLfloat* uOut, GLfloat* vOut);
|
|
||||||
|
|
||||||
// returns the default Display
|
// returns the default Display
|
||||||
sp<const DisplayDevice> getDefaultDisplayDevice() const {
|
sp<const DisplayDevice> getDefaultDisplayDevice() const {
|
||||||
return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
|
return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
|
||||||
|
@ -202,6 +194,10 @@ private:
|
||||||
uint32_t* width, uint32_t* height, PixelFormat* format,
|
uint32_t* width, uint32_t* height, PixelFormat* format,
|
||||||
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
|
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
|
||||||
uint32_t maxLayerZ);
|
uint32_t maxLayerZ);
|
||||||
|
virtual status_t captureScreen(const sp<IBinder>& display,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ);
|
||||||
// called when screen needs to turn off
|
// called when screen needs to turn off
|
||||||
virtual void blank(const sp<IBinder>& display);
|
virtual void blank(const sp<IBinder>& display);
|
||||||
// called when screen is turning back on
|
// called when screen is turning back on
|
||||||
|
@ -306,10 +302,18 @@ private:
|
||||||
|
|
||||||
void startBootAnim();
|
void startBootAnim();
|
||||||
|
|
||||||
status_t captureScreenImplLocked(const sp<IBinder>& display, sp<IMemoryHeap>* heap,
|
status_t captureScreenImplLocked(
|
||||||
uint32_t* width, uint32_t* height, PixelFormat* format,
|
const sp<const DisplayDevice>& hw,
|
||||||
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
|
sp<IMemoryHeap>* heap,
|
||||||
uint32_t maxLayerZ);
|
uint32_t* width, uint32_t* height, PixelFormat* format,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
|
||||||
|
uint32_t maxLayerZ);
|
||||||
|
|
||||||
|
status_t captureScreenImplLocked(
|
||||||
|
const sp<const DisplayDevice>& hw,
|
||||||
|
const sp<IGraphicBufferProducer>& producer,
|
||||||
|
uint32_t reqWidth, uint32_t reqHeight,
|
||||||
|
uint32_t minLayerZ, uint32_t maxLayerZ);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* EGL
|
* EGL
|
||||||
|
|
Loading…
Reference in New Issue