Merge "rework how we take screenshots for a CPU consumer" into jb-mr2-dev

This commit is contained in:
Mathias Agopian 2013-03-20 22:14:55 +00:00 committed by Android (Google) Code Review
commit ff7c2342e2
6 changed files with 149 additions and 190 deletions

View File

@ -95,14 +95,6 @@ public:
virtual bool authenticateSurfaceTexture( virtual bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& surface) const = 0; const sp<IGraphicBufferProducer>& surface) const = 0;
/* Capture the specified screen. requires READ_FRAME_BUFFER permission
* This function will fail if there is a secure window on screen.
*/
virtual status_t captureScreen(const sp<IBinder>& display, sp<IMemoryHeap>* heap,
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth, uint32_t reqHeight,
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
* requires ACCESS_SURFACE_FLINGER permission. * requires ACCESS_SURFACE_FLINGER permission.
*/ */
@ -123,7 +115,8 @@ public:
virtual status_t captureScreen(const sp<IBinder>& display, virtual status_t captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
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,
bool isCpuConsumer) = 0;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -141,7 +134,6 @@ public:
GET_BUILT_IN_DISPLAY, GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE, SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE, AUTHENTICATE_SURFACE,
CAPTURE_SCREEN_DEPRECATED,
BLANK, BLANK,
UNBLANK, UNBLANK,
GET_DISPLAY_INFO, GET_DISPLAY_INFO,

View File

@ -30,6 +30,7 @@
#include <ui/PixelFormat.h> #include <ui/PixelFormat.h>
#include <gui/CpuConsumer.h>
#include <gui/SurfaceControl.h> #include <gui/SurfaceControl.h>
namespace android { namespace android {
@ -38,7 +39,6 @@ namespace android {
class DisplayInfo; class DisplayInfo;
class Composer; class Composer;
class IMemoryHeap;
class ISurfaceComposerClient; class ISurfaceComposerClient;
class IGraphicBufferProducer; class IGraphicBufferProducer;
class Region; class Region;
@ -164,10 +164,9 @@ public:
uint32_t minLayerZ, uint32_t maxLayerZ); uint32_t minLayerZ, uint32_t maxLayerZ);
private: private:
sp<IMemoryHeap> mHeap; mutable sp<CpuConsumer> mCpuConsumer;
uint32_t mWidth; CpuConsumer::LockedBuffer mBuffer;
uint32_t mHeight; bool mHaveBuffer;
PixelFormat mFormat;
public: public:
ScreenshotClient(); ScreenshotClient();
@ -180,6 +179,8 @@ public:
uint32_t reqWidth, uint32_t reqHeight, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ); uint32_t minLayerZ, uint32_t maxLayerZ);
sp<CpuConsumer> getCpuConsumer() const;
// release memory occupied by the screenshot // release memory occupied by the screenshot
void release(); void release();

View File

@ -102,31 +102,11 @@ public:
remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
} }
virtual status_t captureScreen(
const sp<IBinder>& display, sp<IMemoryHeap>* heap,
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
data.writeInt32(reqWidth);
data.writeInt32(reqHeight);
data.writeInt32(minLayerZ);
data.writeInt32(maxLayerZ);
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_DEPRECATED, data, &reply);
*heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
*width = reply.readInt32();
*height = reply.readInt32();
*format = reply.readInt32();
return reply.readInt32();
}
virtual status_t captureScreen(const sp<IBinder>& display, virtual status_t captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ) uint32_t minLayerZ, uint32_t maxLayerZ,
bool isCpuConsumer)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@ -136,6 +116,7 @@ public:
data.writeInt32(reqHeight); data.writeInt32(reqHeight);
data.writeInt32(minLayerZ); data.writeInt32(minLayerZ);
data.writeInt32(maxLayerZ); data.writeInt32(maxLayerZ);
data.writeInt32(isCpuConsumer);
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32(); return reply.readInt32();
} }
@ -285,24 +266,6 @@ status_t BnSurfaceComposer::onTransact(
CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply);
bootFinished(); bootFinished();
} break; } break;
case CAPTURE_SCREEN_DEPRECATED: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
uint32_t reqWidth = data.readInt32();
uint32_t reqHeight = data.readInt32();
uint32_t minLayerZ = data.readInt32();
uint32_t maxLayerZ = data.readInt32();
sp<IMemoryHeap> heap;
uint32_t w, h;
PixelFormat f;
status_t res = captureScreen(display, &heap, &w, &h, &f,
reqWidth, reqHeight, minLayerZ, maxLayerZ);
reply->writeStrongBinder(heap->asBinder());
reply->writeInt32(w);
reply->writeInt32(h);
reply->writeInt32(f);
reply->writeInt32(res);
} break;
case CAPTURE_SCREEN: { case CAPTURE_SCREEN: {
CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder(); sp<IBinder> display = data.readStrongBinder();
@ -312,8 +275,10 @@ status_t BnSurfaceComposer::onTransact(
uint32_t reqHeight = data.readInt32(); uint32_t reqHeight = data.readInt32();
uint32_t minLayerZ = data.readInt32(); uint32_t minLayerZ = data.readInt32();
uint32_t maxLayerZ = data.readInt32(); uint32_t maxLayerZ = data.readInt32();
bool isCpuConsumer = data.readInt32();
status_t res = captureScreen(display, producer, status_t res = captureScreen(display, producer,
reqWidth, reqHeight, minLayerZ, maxLayerZ); reqWidth, reqHeight, minLayerZ, maxLayerZ,
isCpuConsumer);
reply->writeInt32(res); reply->writeInt32(res);
} break; } break;
case AUTHENTICATE_SURFACE: { case AUTHENTICATE_SURFACE: {

View File

@ -31,6 +31,7 @@
#include <ui/DisplayInfo.h> #include <ui/DisplayInfo.h>
#include <gui/CpuConsumer.h>
#include <gui/IGraphicBufferProducer.h> #include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposerClient.h> #include <gui/ISurfaceComposerClient.h>
@ -617,30 +618,21 @@ status_t ScreenshotClient::capture(
sp<ISurfaceComposer> s(ComposerService::getComposerService()); sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT; if (s == NULL) return NO_INIT;
return s->captureScreen(display, producer, return s->captureScreen(display, producer,
reqWidth, reqHeight, minLayerZ, maxLayerZ); reqWidth, reqHeight, minLayerZ, maxLayerZ,
false);
} }
ScreenshotClient::ScreenshotClient() ScreenshotClient::ScreenshotClient()
: mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) { : mHaveBuffer(false) {
memset(&mBuffer, 0, sizeof(mBuffer));
} }
status_t ScreenshotClient::update(const sp<IBinder>& display) { sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (mCpuConsumer == NULL) {
if (s == NULL) return NO_INIT; mCpuConsumer = new CpuConsumer(1);
mHeap = 0; mCpuConsumer->setName(String8("ScreenshotClient"));
return s->captureScreen(display, &mHeap,
&mWidth, &mHeight, &mFormat, 0, 0,
0, -1UL);
} }
return mCpuConsumer;
status_t ScreenshotClient::update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
mHeap = 0;
return s->captureScreen(display, &mHeap,
&mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
0, -1UL);
} }
status_t ScreenshotClient::update(const sp<IBinder>& display, status_t ScreenshotClient::update(const sp<IBinder>& display,
@ -648,38 +640,66 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
uint32_t minLayerZ, uint32_t maxLayerZ) { uint32_t minLayerZ, uint32_t maxLayerZ) {
sp<ISurfaceComposer> s(ComposerService::getComposerService()); sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT; if (s == NULL) return NO_INIT;
mHeap = 0; sp<CpuConsumer> cpuConsumer = getCpuConsumer();
return s->captureScreen(display, &mHeap,
&mWidth, &mHeight, &mFormat, reqWidth, reqHeight, if (mHaveBuffer) {
minLayerZ, maxLayerZ); mCpuConsumer->unlockBuffer(mBuffer);
memset(&mBuffer, 0, sizeof(mBuffer));
mHaveBuffer = false;
}
status_t err = s->captureScreen(display,cpuConsumer->getBufferQueue(),
reqWidth, reqHeight, minLayerZ, maxLayerZ, true);
if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer);
if (err == NO_ERROR) {
mHaveBuffer = true;
}
}
return err;
}
status_t ScreenshotClient::update(const sp<IBinder>& display) {
return ScreenshotClient::update(display, 0, 0, 0, -1UL);
}
status_t ScreenshotClient::update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight) {
return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL);
} }
void ScreenshotClient::release() { void ScreenshotClient::release() {
mHeap = 0; if (mHaveBuffer) {
mCpuConsumer->unlockBuffer(mBuffer);
memset(&mBuffer, 0, sizeof(mBuffer));
mHaveBuffer = false;
}
mCpuConsumer.clear();
} }
void const* ScreenshotClient::getPixels() const { void const* ScreenshotClient::getPixels() const {
return mHeap->getBase(); return mBuffer.data;
} }
uint32_t ScreenshotClient::getWidth() const { uint32_t ScreenshotClient::getWidth() const {
return mWidth; return mBuffer.width;
} }
uint32_t ScreenshotClient::getHeight() const { uint32_t ScreenshotClient::getHeight() const {
return mHeight; return mBuffer.height;
} }
PixelFormat ScreenshotClient::getFormat() const { PixelFormat ScreenshotClient::getFormat() const {
return mFormat; return mBuffer.format;
} }
uint32_t ScreenshotClient::getStride() const { uint32_t ScreenshotClient::getStride() const {
return mWidth; return mBuffer.stride;
} }
size_t ScreenshotClient::getSize() const { size_t ScreenshotClient::getSize() const {
return mHeap->getSize(); return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -2416,7 +2416,6 @@ status_t SurfaceFlinger::onTransact(
break; break;
} }
case CAPTURE_SCREEN: case CAPTURE_SCREEN:
case CAPTURE_SCREEN_DEPRECATED:
{ {
// codes that require permission check // codes that require permission check
IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self();
@ -2511,7 +2510,8 @@ void SurfaceFlinger::repaintEverything() {
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ) { uint32_t minLayerZ, uint32_t maxLayerZ,
bool isCpuConsumer) {
if (CC_UNLIKELY(display == 0)) if (CC_UNLIKELY(display == 0))
return BAD_VALUE; return BAD_VALUE;
@ -2525,16 +2525,18 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<IGraphicBufferProducer> producer; sp<IGraphicBufferProducer> producer;
uint32_t reqWidth, reqHeight; uint32_t reqWidth, reqHeight;
uint32_t minLayerZ,maxLayerZ; uint32_t minLayerZ,maxLayerZ;
bool isCpuConsumer;
status_t result; status_t result;
public: public:
MessageCaptureScreen(SurfaceFlinger* flinger, MessageCaptureScreen(SurfaceFlinger* flinger,
const sp<IBinder>& display, const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ) uint32_t minLayerZ, uint32_t maxLayerZ, bool isCpuConsumer)
: flinger(flinger), display(display), producer(producer), : flinger(flinger), display(display), producer(producer),
reqWidth(reqWidth), reqHeight(reqHeight), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
isCpuConsumer(isCpuConsumer),
result(PERMISSION_DENIED) result(PERMISSION_DENIED)
{ {
} }
@ -2544,14 +2546,24 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
virtual bool handler() { virtual bool handler() {
Mutex::Autolock _l(flinger->mStateLock); Mutex::Autolock _l(flinger->mStateLock);
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
result = flinger->captureScreenImplLocked(hw, producer, // TODO: if we know the GL->CPU path works, we can call
reqWidth, reqHeight, minLayerZ, maxLayerZ); // captureScreenImplLocked() directly, instead of using the
// "CpuConsumer" version, which is much less efficient -- it is
// however needed by some older drivers.
if (isCpuConsumer) {
result = flinger->captureScreenImplCpuConsumerLocked(hw,
producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
} else {
result = flinger->captureScreenImplLocked(hw,
producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
}
return true; return true;
} }
}; };
sp<MessageBase> msg = new MessageCaptureScreen(this, sp<MessageBase> msg = new MessageCaptureScreen(this,
display, producer, reqWidth, reqHeight, minLayerZ, maxLayerZ); display, producer, reqWidth, reqHeight, minLayerZ, maxLayerZ,
isCpuConsumer);
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();
@ -2655,18 +2667,15 @@ status_t SurfaceFlinger::captureScreenImplLocked(
} }
eglDestroySurface(mEGLDisplay, eglSurface); eglDestroySurface(mEGLDisplay, eglSurface);
return NO_ERROR; return NO_ERROR;
} }
// ---------------------------------------------------------------------------
// Capture screen into an IMemoryHeap (legacy)
// ---------------------------------------------------------------------------
status_t SurfaceFlinger::captureScreenImplLocked( status_t SurfaceFlinger::captureScreenImplCpuConsumerLocked(
const sp<const DisplayDevice>& hw, const sp<const DisplayDevice>& hw,
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) uint32_t minLayerZ, uint32_t maxLayerZ)
{ {
ATRACE_CALL(); ATRACE_CALL();
@ -2689,7 +2698,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(
// call the new screenshot taking code, passing a BufferQueue to it // call the new screenshot taking code, passing a BufferQueue to it
status_t result = captureScreenImplLocked(hw, status_t result = captureScreenImplLocked(hw,
consumer->getBufferQueue(), sw, sh, minLayerZ, maxLayerZ); consumer->getBufferQueue(), reqWidth, reqHeight, minLayerZ, maxLayerZ);
if (result == NO_ERROR) { if (result == NO_ERROR) {
result = consumer->updateTexImage(); result = consumer->updateTexImage();
@ -2701,31 +2710,64 @@ status_t SurfaceFlinger::captureScreenImplLocked(
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
sp<GraphicBuffer> buf(consumer->getCurrentBuffer()); reqWidth = consumer->getCurrentBuffer()->getWidth();
sw = buf->getWidth(); reqHeight = consumer->getCurrentBuffer()->getHeight();
sh = buf->getHeight();
size_t size = sw * sh * 4;
// allocate shared memory large enough to hold the {
// screen capture // in this block we render the screenshot into the
sp<MemoryHeapBase> base( // CpuConsumer using glReadPixels from our GLConsumer,
new MemoryHeapBase(size, 0, "screen-capture") ); // Some older drivers don't support the GL->CPU path so
void* const ptr = base->getBase(); // have to wrap it with a CPU->CPU path, which is what
if (ptr != MAP_FAILED) { // glReadPixels essentially is
// capture the screen with glReadPixels()
ScopedTrace _t(ATRACE_TAG, "glReadPixels"); sp<Surface> sur = new Surface(producer);
glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); ANativeWindow* window = sur.get();
if (glGetError() == GL_NO_ERROR) { ANativeWindowBuffer* buffer;
*heap = base; void* vaddr;
*w = sw;
*h = sh; if (native_window_api_connect(window,
*f = PIXEL_FORMAT_RGBA_8888; NATIVE_WINDOW_API_CPU) == NO_ERROR) {
result = NO_ERROR; int err = 0;
} else { err = native_window_set_buffers_dimensions(window,
result = NO_MEMORY; reqWidth, reqHeight);
err |= native_window_set_buffers_format(window,
HAL_PIXEL_FORMAT_RGBA_8888);
err |= native_window_set_usage(window,
GRALLOC_USAGE_SW_READ_OFTEN |
GRALLOC_USAGE_SW_WRITE_OFTEN);
if (err == NO_ERROR) {
if (native_window_dequeue_buffer_and_wait(window,
&buffer) == NO_ERROR) {
sp<GraphicBuffer> buf =
static_cast<GraphicBuffer*>(buffer);
if (buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
&vaddr) == NO_ERROR) {
if (buffer->stride != int(reqWidth)) {
// we're unlucky here, glReadPixels is
// not able to deal with a stride not
// equal to the width.
uint32_t* tmp = new uint32_t[reqWidth*reqHeight];
if (tmp != NULL) {
glReadPixels(0, 0, reqWidth, reqHeight,
GL_RGBA, GL_UNSIGNED_BYTE, tmp);
for (size_t y=0 ; y<reqHeight ; y++) {
memcpy((uint32_t*)vaddr + y*buffer->stride,
tmp + y*reqWidth, reqWidth*4);
}
delete [] tmp;
} }
} else { } else {
result = NO_MEMORY; glReadPixels(0, 0, reqWidth, reqHeight,
GL_RGBA, GL_UNSIGNED_BYTE, vaddr);
}
buf->unlock();
}
window->queueBuffer(window, buffer, -1);
}
}
native_window_api_disconnect(window, NATIVE_WINDOW_API_CPU);
}
} }
// back to main framebuffer // back to main framebuffer
@ -2742,63 +2784,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(
return result; return result;
} }
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<IMemoryHeap>* heap,
uint32_t* outWidth, uint32_t* outHeight, PixelFormat* outFormat,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ)
{
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
class MessageCaptureScreen : public MessageBase {
SurfaceFlinger* flinger;
sp<IBinder> display;
sp<IMemoryHeap>* heap;
uint32_t* outWidth;
uint32_t* outHeight;
PixelFormat* outFormat;
uint32_t reqWidth;
uint32_t reqHeight;
uint32_t minLayerZ;
uint32_t maxLayerZ;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
const sp<IBinder>& display, sp<IMemoryHeap>* heap,
uint32_t* outWidth, uint32_t* outHeight, PixelFormat* outFormat,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ)
: flinger(flinger), display(display), heap(heap),
outWidth(outWidth), outHeight(outHeight), outFormat(outFormat),
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, heap,
outWidth, outHeight, outFormat,
reqWidth, reqHeight, minLayerZ, maxLayerZ);
return true;
}
};
sp<MessageBase> msg = new MessageCaptureScreen(this, display, heap,
outWidth, outHeight, outFormat,
reqWidth, reqHeight, minLayerZ, maxLayerZ);
status_t res = postMessageSync(msg);
if (res == NO_ERROR) {
res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
}
return res;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
SurfaceFlinger::LayerVector::LayerVector() { SurfaceFlinger::LayerVector::LayerVector() {

View File

@ -185,14 +185,10 @@ private:
virtual bool authenticateSurfaceTexture( virtual bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) const; const sp<IGraphicBufferProducer>& bufferProducer) const;
virtual sp<IDisplayEventConnection> createDisplayEventConnection(); virtual sp<IDisplayEventConnection> createDisplayEventConnection();
virtual status_t captureScreen(const sp<IBinder>& display, sp<IMemoryHeap>* heap,
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
uint32_t maxLayerZ);
virtual status_t captureScreen(const sp<IBinder>& display, virtual status_t captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ); uint32_t minLayerZ, uint32_t maxLayerZ, bool isCpuConsumer);
// 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
@ -297,17 +293,17 @@ private:
status_t captureScreenImplLocked( status_t captureScreenImplLocked(
const sp<const DisplayDevice>& hw, const sp<const DisplayDevice>& hw,
sp<IMemoryHeap>* heap, const sp<IGraphicBufferProducer>& producer,
uint32_t* width, uint32_t* height, PixelFormat* format, uint32_t reqWidth, uint32_t reqHeight,
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ);
uint32_t maxLayerZ);
status_t captureScreenImplLocked( status_t captureScreenImplCpuConsumerLocked(
const sp<const DisplayDevice>& hw, const sp<const DisplayDevice>& hw,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ); uint32_t minLayerZ, uint32_t maxLayerZ);
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
* EGL * EGL
*/ */