Bring back support for glReadPixels screenshot path

Squashed commit of the following:

commit 012d3fe41d1d6cd38a0858b59145e9a4447641fa
Author: Hashcode <hashcode0f@gmail.com>
Date:   Sun Dec 8 19:36:50 2013 +0000

    sf: Always use opengles for screen capture

    Go back to the usage of GRALLOC_USAGE_HW_TEXTURE and GRALLOC_USAGE_HW_RENDERER
    in captureScreenImplLocked regardless of useReadPixels value

    This fixes the EGL_NO_IMAGE_KHR error returned from
    eglCreateImageKHR (blank images returned from screenshot path)

    Change-Id: I62fe90a081607b9e89c67f3dcfd34c84efc89d35

commit 4866ddf98ac98d8e22a1cd6a21894bb17f274588
Author: Ricardo Cerqueira <cyanogenmod@cerqueira.org>
Date:   Thu Oct 31 03:53:39 2013 +0000

    Revert "remove support for glReadPixels screenshot path"

    This reverts commit 3ca76f416b.

    Conflicts:
    	include/gui/ISurfaceComposer.h
    	libs/gui/ISurfaceComposer.cpp
    	libs/gui/SurfaceComposerClient.cpp
    	services/surfaceflinger/SurfaceFlinger.cpp
    	services/surfaceflinger/SurfaceFlinger.h

    Change-Id: I8c239e533757af770e418dbb198f5a86c736961f

Change-Id: I8c239e533757af770e418dbb198f5a86c736961f
This commit is contained in:
Pawit Pornkitprasan 2014-11-18 08:38:33 +07:00 committed by Gerrit Code Review
parent bcce313fea
commit fd1fb639a1
11 changed files with 114 additions and 46 deletions

View File

@ -145,7 +145,8 @@ public:
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, bool useIdentityTransform,
Rotation rotation = eRotateNone) = 0; Rotation rotation = eRotateNone,
bool isCpuConsumer = false) = 0;
/* Clears the frame statistics for animations. /* Clears the frame statistics for animations.
* *

View File

@ -103,7 +103,8 @@ public:
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, bool useIdentityTransform,
ISurfaceComposer::Rotation rotation) ISurfaceComposer::Rotation rotation,
bool isCpuConsumer)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@ -116,6 +117,7 @@ public:
data.writeUint32(maxLayerZ); data.writeUint32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(useIdentityTransform));
data.writeInt32(static_cast<int32_t>(rotation)); data.writeInt32(static_cast<int32_t>(rotation));
data.writeInt32(isCpuConsumer);
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32(); return reply.readInt32();
} }
@ -361,11 +363,13 @@ status_t BnSurfaceComposer::onTransact(
uint32_t maxLayerZ = data.readUint32(); uint32_t maxLayerZ = data.readUint32();
bool useIdentityTransform = static_cast<bool>(data.readInt32()); bool useIdentityTransform = static_cast<bool>(data.readInt32());
int32_t rotation = data.readInt32(); int32_t rotation = data.readInt32();
bool isCpuConsumer = data.readInt32();
status_t res = captureScreen(display, producer, status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform, useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation)); static_cast<ISurfaceComposer::Rotation>(rotation),
isCpuConsumer);
reply->writeInt32(res); reply->writeInt32(res);
return NO_ERROR; return NO_ERROR;
} }

View File

@ -691,7 +691,8 @@ 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, sourceCrop, return s->captureScreen(display, producer, sourceCrop,
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform); reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
ISurfaceComposer::eRotateNone, false);
} }
ScreenshotClient::ScreenshotClient() ScreenshotClient::ScreenshotClient()
@ -729,7 +730,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
status_t err = s->captureScreen(display, mProducer, sourceCrop, status_t err = s->captureScreen(display, mProducer, sourceCrop,
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation)); static_cast<ISurfaceComposer::Rotation>(rotation), true);
if (err == NO_ERROR) { if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer); err = mCpuConsumer->lockNextBuffer(&mBuffer);

View File

@ -210,28 +210,46 @@ void GLES11RenderEngine::disableBlending() {
} }
void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
uint32_t* texName, uint32_t* fbName, uint32_t* status) { uint32_t* texName, uint32_t* fbName, uint32_t* status,
bool useReadPixels, int reqWidth, int reqHeight) {
GLuint tname, name; GLuint tname, name;
// turn our EGLImage into a texture if (!useReadPixels) {
glGenTextures(1, &tname); // turn our EGLImage into a texture
glBindTexture(GL_TEXTURE_2D, tname); glGenTextures(1, &tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); glBindTexture(GL_TEXTURE_2D, tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
// create a Framebuffer Object to render into // create a Framebuffer Object to render into
glGenFramebuffersOES(1, &name); glGenFramebuffersOES(1, &name);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
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);
} else {
// since we're going to use glReadPixels() anyways,
// use an intermediate renderbuffer instead
glGenRenderbuffersOES(1, &tname);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, reqWidth, reqHeight);
// create a FBO to render into
glGenFramebuffersOES(1, &name);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES, tname);
}
*status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
*texName = tname; *texName = tname;
*fbName = name; *fbName = name;
} }
void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
bool useReadPixels) {
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glDeleteFramebuffersOES(1, &fbName); glDeleteFramebuffersOES(1, &fbName);
glDeleteTextures(1, &texName); if (!useReadPixels)
glDeleteTextures(1, &texName);
else
glDeleteRenderbuffersOES(1, &texName);
} }
void GLES11RenderEngine::setupFillWithColor(float r, float g, float b, float a) { void GLES11RenderEngine::setupFillWithColor(float r, float g, float b, float a) {

View File

@ -40,8 +40,9 @@ class GLES11RenderEngine : public RenderEngine {
GLint mMaxTextureSize; GLint mMaxTextureSize;
virtual void bindImageAsFramebuffer(EGLImageKHR image, virtual void bindImageAsFramebuffer(EGLImageKHR image,
uint32_t* texName, uint32_t* fbName, uint32_t* status); uint32_t* texName, uint32_t* fbName, uint32_t* status, bool useReadPixels,
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName); int reqWidth, int reqHeight);
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);
public: public:
GLES11RenderEngine(); GLES11RenderEngine();

View File

@ -185,27 +185,44 @@ void GLES20RenderEngine::disableBlending() {
void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
uint32_t* texName, uint32_t* fbName, uint32_t* status) { uint32_t* texName, uint32_t* fbName, uint32_t* status,
bool useReadPixels, int reqWidth, int reqHeight) {
GLuint tname, name; GLuint tname, name;
// turn our EGLImage into a texture if (!useReadPixels) {
glGenTextures(1, &tname); // turn our EGLImage into a texture
glBindTexture(GL_TEXTURE_2D, tname); glGenTextures(1, &tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); glBindTexture(GL_TEXTURE_2D, tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
// create a Framebuffer Object to render into // create a Framebuffer Object to render into
glGenFramebuffers(1, &name); glGenFramebuffers(1, &name);
glBindFramebuffer(GL_FRAMEBUFFER, name); glBindFramebuffer(GL_FRAMEBUFFER, name);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
} else {
// since we're going to use glReadPixels() anyways,
// use an intermediate renderbuffer instead
glGenRenderbuffers(1, &tname);
glBindRenderbuffer(GL_RENDERBUFFER, tname);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, reqWidth, reqHeight);
// create a FBO to render into
glGenFramebuffers(1, &name);
glBindFramebuffer(GL_FRAMEBUFFER, name);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, tname);
}
*status = glCheckFramebufferStatus(GL_FRAMEBUFFER); *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
*texName = tname; *texName = tname;
*fbName = name; *fbName = name;
} }
void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
bool useReadPixels) {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbName); glDeleteFramebuffers(1, &fbName);
glDeleteTextures(1, &texName); if (!useReadPixels)
glDeleteTextures(1, &texName);
else
glDeleteRenderbuffers(1, &texName);
} }
void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) { void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {

View File

@ -55,8 +55,9 @@ class GLES20RenderEngine : public RenderEngine {
Vector<Group> mGroupStack; Vector<Group> mGroupStack;
virtual void bindImageAsFramebuffer(EGLImageKHR image, virtual void bindImageAsFramebuffer(EGLImageKHR image,
uint32_t* texName, uint32_t* fbName, uint32_t* status); uint32_t* texName, uint32_t* fbName, uint32_t* status,
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName); bool useReadPixels, int reqWidth, int reqHeight);
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);
public: public:
GLES20RenderEngine(); GLES20RenderEngine();

View File

@ -262,9 +262,11 @@ void RenderEngine::dump(String8& result) {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer( RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
RenderEngine& engine, EGLImageKHR image) : mEngine(engine) RenderEngine& engine, EGLImageKHR image, bool useReadPixels,
int reqWidth, int reqHeight) : mEngine(engine), mUseReadPixels(useReadPixels)
{ {
mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus); mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus,
useReadPixels, reqWidth, reqHeight);
ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
"glCheckFramebufferStatusOES error %d", mStatus); "glCheckFramebufferStatusOES error %d", mStatus);
@ -272,7 +274,7 @@ RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() { RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
// back to main framebuffer // back to main framebuffer
mEngine.unbindFramebuffer(mTexName, mFbName); mEngine.unbindFramebuffer(mTexName, mFbName, mUseReadPixels);
} }
status_t RenderEngine::BindImageAsFramebuffer::getStatus() const { status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {

View File

@ -51,8 +51,11 @@ class RenderEngine {
EGLContext mEGLContext; EGLContext mEGLContext;
void setEGLHandles(EGLConfig config, EGLContext ctxt); void setEGLHandles(EGLConfig config, EGLContext ctxt);
virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0; virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName,
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0; uint32_t* fbName, uint32_t* status, bool useReadPixels, int reqWidth,
int reqHeight) = 0;
virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName,
bool useReadPixels) = 0;
protected: protected:
RenderEngine(); RenderEngine();
@ -83,8 +86,10 @@ public:
RenderEngine& mEngine; RenderEngine& mEngine;
uint32_t mTexName, mFbName; uint32_t mTexName, mFbName;
uint32_t mStatus; uint32_t mStatus;
bool mUseReadPixels;
public: public:
BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image); BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image,
bool useReadPixels, int reqWidth, int reqHeight);
~BindImageAsFramebuffer(); ~BindImageAsFramebuffer();
int getStatus() const; int getStatus() const;
}; };

View File

@ -3160,7 +3160,8 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { bool useIdentityTransform, ISurfaceComposer::Rotation rotation,
bool useReadPixels) {
if (CC_UNLIKELY(display == 0)) if (CC_UNLIKELY(display == 0))
return BAD_VALUE; return BAD_VALUE;
@ -3210,6 +3211,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
uint32_t minLayerZ,maxLayerZ; uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform; bool useIdentityTransform;
Transform::orientation_flags rotation; Transform::orientation_flags rotation;
bool useReadPixels;
status_t result; status_t result;
public: public:
MessageCaptureScreen(SurfaceFlinger* flinger, MessageCaptureScreen(SurfaceFlinger* flinger,
@ -3217,12 +3219,14 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, Transform::orientation_flags rotation) bool useIdentityTransform, Transform::orientation_flags rotation,
bool useReadPixels)
: flinger(flinger), display(display), producer(producer), : flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform), useIdentityTransform(useIdentityTransform),
rotation(rotation), rotation(rotation),
useReadPixels(useReadPixels),
result(PERMISSION_DENIED) result(PERMISSION_DENIED)
{ {
} }
@ -3232,9 +3236,10 @@ 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));
bool useReadPixels = this->useReadPixels && !flinger->mGpuToCpuSupported;
result = flinger->captureScreenImplLocked(hw, producer, result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform, rotation); useIdentityTransform, rotation, useReadPixels);
static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
return true; return true;
} }
@ -3257,7 +3262,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<MessageBase> msg = new MessageCaptureScreen(this, sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ), display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform, rotationFlags); useIdentityTransform, rotationFlags, useReadPixels);
status_t res = postMessageAsync(msg); status_t res = postMessageAsync(msg);
if (res == NO_ERROR) { if (res == NO_ERROR) {
@ -3347,7 +3352,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, Transform::orientation_flags rotation) bool useIdentityTransform, Transform::orientation_flags rotation,
bool useReadPixels)
{ {
ATRACE_CALL(); ATRACE_CALL();
@ -3399,7 +3405,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
if (image != EGL_NO_IMAGE_KHR) { if (image != EGL_NO_IMAGE_KHR) {
// this binds the given EGLImage as a framebuffer for the // this binds the given EGLImage as a framebuffer for the
// duration of this scope. // duration of this scope.
RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image,
useReadPixels, reqWidth, reqHeight);
if (imageBond.getStatus() == NO_ERROR) { if (imageBond.getStatus() == NO_ERROR) {
// this will in fact render into our dequeued buffer // this will in fact render into our dequeued buffer
// via an FBO, which means we didn't have to create // via an FBO, which means we didn't have to create
@ -3446,6 +3453,15 @@ status_t SurfaceFlinger::captureScreenImplLocked(
ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
} }
} }
if (useReadPixels) {
sp<GraphicBuffer> buf = static_cast<GraphicBuffer*>(buffer);
void* vaddr;
if (buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr) == NO_ERROR) {
getRenderEngine().readPixels(0, 0, buffer->stride, reqHeight,
(uint32_t *)vaddr);
buf->unlock();
}
}
if (DEBUG_SCREENSHOTS) { if (DEBUG_SCREENSHOTS) {
uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);

View File

@ -212,7 +212,8 @@ private:
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, ISurfaceComposer::Rotation rotation); bool useIdentityTransform, ISurfaceComposer::Rotation rotation,
bool isCpuConsumer);
virtual status_t getDisplayStats(const sp<IBinder>& display, virtual status_t getDisplayStats(const sp<IBinder>& display,
DisplayStatInfo* stats); DisplayStatInfo* stats);
virtual status_t getDisplayConfigs(const sp<IBinder>& display, virtual status_t getDisplayConfigs(const sp<IBinder>& display,
@ -366,7 +367,8 @@ private:
const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ, uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform, Transform::orientation_flags rotation); bool useIdentityTransform, Transform::orientation_flags rotation,
bool useReadPixels);
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
* EGL * EGL