Allow disabling layer rotation during screenshots

Add the ability to ignore layers' transformation matrices during
screenshot capture, which will allow the window manager to capture
unrotated images for recents during the device rotation animation.

Bug: 11805195
Change-Id: I854d87bc84ca06ef9a054a454af1c080ee66fbb8
This commit is contained in:
Dan Stoza 2014-02-14 15:03:43 -08:00
parent 87c01edaf6
commit c701401f8c
11 changed files with 96 additions and 58 deletions

View File

@ -120,7 +120,8 @@ public:
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;
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform) = 0;
};
// ----------------------------------------------------------------------------

View File

@ -164,7 +164,8 @@ public:
const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ);
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform);
private:
mutable sp<CpuConsumer> mCpuConsumer;
@ -177,12 +178,14 @@ public:
~ScreenshotClient();
// frees the previous screenshot and capture a new one
status_t update(const sp<IBinder>& display);
status_t update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight);
status_t update(const sp<IBinder>& display, bool useIdentityTransform);
status_t update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ);
bool useIdentityTransform);
status_t update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform);
sp<CpuConsumer> getCpuConsumer() const;

View File

@ -105,7 +105,8 @@ public:
virtual status_t captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ)
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@ -115,6 +116,7 @@ public:
data.writeInt32(reqHeight);
data.writeInt32(minLayerZ);
data.writeInt32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32();
}
@ -285,8 +287,11 @@ status_t BnSurfaceComposer::onTransact(
uint32_t reqHeight = data.readInt32();
uint32_t minLayerZ = data.readInt32();
uint32_t maxLayerZ = data.readInt32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
status_t res = captureScreen(display, producer,
reqWidth, reqHeight, minLayerZ, maxLayerZ);
reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform);
reply->writeInt32(res);
return NO_ERROR;
}

View File

@ -628,11 +628,11 @@ status_t ScreenshotClient::capture(
const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ) {
uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
return s->captureScreen(display, producer,
reqWidth, reqHeight, minLayerZ, maxLayerZ);
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
}
ScreenshotClient::ScreenshotClient()
@ -655,7 +655,8 @@ sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
status_t ScreenshotClient::update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ) {
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
sp<CpuConsumer> cpuConsumer = getCpuConsumer();
@ -667,7 +668,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
}
status_t err = s->captureScreen(display, mBufferQueue,
reqWidth, reqHeight, minLayerZ, maxLayerZ);
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer);
@ -678,13 +679,16 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
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,
bool useIdentityTransform) {
return ScreenshotClient::update(display, 0, 0, 0, -1UL,
useIdentityTransform);
}
status_t ScreenshotClient::update(const sp<IBinder>& display,
uint32_t reqWidth, uint32_t reqHeight) {
return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL);
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) {
return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL,
useIdentityTransform);
}
void ScreenshotClient::release() {

View File

@ -194,6 +194,8 @@ void DisplayDevice::flip(const Region& dirty) const
eglSetSwapRectangleANDROID(dpy, surface,
b.left, b.top, b.width(), b.height());
}
#else
(void) dirty; // Eliminate unused parameter warning
#endif
mPageFlipCount++;

View File

@ -145,7 +145,7 @@ Layer::~Layer() {
// callbacks
// ---------------------------------------------------------------------------
void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
HWComposer::HWCLayerInterface* layer) {
if (layer) {
layer->onDisplayed();
@ -418,7 +418,7 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
layer.setBuffer(mActiveBuffer);
}
void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
HWComposer::HWCLayerInterface& layer) {
int fenceFd = -1;
@ -442,14 +442,20 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
// ---------------------------------------------------------------------------
void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
onDraw(hw, clip);
onDraw(hw, clip, false);
}
void Layer::draw(const sp<const DisplayDevice>& hw) {
onDraw( hw, Region(hw->bounds()) );
void Layer::draw(const sp<const DisplayDevice>& hw,
bool useIdentityTransform) const {
onDraw(hw, Region(hw->bounds()), useIdentityTransform);
}
void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
void Layer::draw(const sp<const DisplayDevice>& hw) const {
onDraw(hw, Region(hw->bounds()), false);
}
void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
bool useIdentityTransform) const
{
ATRACE_CALL();
@ -540,16 +546,17 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
} else {
engine.setupLayerBlackedOut();
}
drawWithOpenGL(hw, clip);
drawWithOpenGL(hw, clip, useIdentityTransform);
engine.disableTexturing();
}
void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
float red, float green, float blue, float alpha) const
void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
const Region& /* clip */, float red, float green, float blue,
float alpha) const
{
RenderEngine& engine(mFlinger->getRenderEngine());
computeGeometry(hw, mMesh);
computeGeometry(hw, mMesh, false);
engine.setupFillWithColor(red, green, blue, alpha);
engine.drawMesh(mMesh);
}
@ -559,12 +566,12 @@ void Layer::clearWithOpenGL(
clearWithOpenGL(hw, clip, 0,0,0,0);
}
void Layer::drawWithOpenGL(
const sp<const DisplayDevice>& hw, const Region& clip) const {
void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
const Region& /* clip */, bool useIdentityTransform) const {
const uint32_t fbHeight = hw->getHeight();
const State& s(getDrawingState());
computeGeometry(hw, mMesh);
computeGeometry(hw, mMesh, useIdentityTransform);
/*
* NOTE: the way we compute the texture coordinates here produces
@ -634,10 +641,12 @@ bool Layer::getOpacityForFormat(uint32_t format) {
// local state
// ----------------------------------------------------------------------------
void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
bool useIdentityTransform) const
{
const Layer::State& s(getDrawingState());
const Transform tr(hw->getTransform() * s.transform);
const Transform tr(useIdentityTransform ?
hw->getTransform() : hw->getTransform() * s.transform);
const uint32_t hw_h = hw->getHeight();
Rect win(s.active.w, s.active.h);
if (!s.active.crop.isEmpty()) {

View File

@ -135,7 +135,8 @@ public:
uint32_t getTransactionFlags(uint32_t flags);
uint32_t setTransactionFlags(uint32_t flags);
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const;
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
bool useIdentityTransform) const;
Rect computeBounds() const;
sp<IBinder> getHandle();
@ -182,7 +183,8 @@ protected:
/*
* onDraw - draws the surface.
*/
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
bool useIdentityTransform) const;
public:
// -----------------------------------------------------------------------
@ -216,7 +218,8 @@ public:
* and calls onDraw().
*/
void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
void draw(const sp<const DisplayDevice>& hw);
void draw(const sp<const DisplayDevice>& hw, bool useIdentityTransform) const;
void draw(const sp<const DisplayDevice>& hw) const;
/*
* doTransaction - process the transaction. This is a good place to figure
@ -326,7 +329,8 @@ private:
// drawing
void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
float r, float g, float b, float alpha) const;
void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
bool useIdentityTransform) const;
// -----------------------------------------------------------------------

View File

@ -39,12 +39,13 @@ LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
LayerDim::~LayerDim() {
}
void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
void LayerDim::onDraw(const sp<const DisplayDevice>& hw,
const Region& /* clip */, bool useIdentityTransform) const
{
const State& s(getDrawingState());
if (s.alpha>0) {
Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
computeGeometry(hw, mesh);
computeGeometry(hw, mesh, useIdentityTransform);
RenderEngine& engine(mFlinger->getRenderEngine());
engine.setupDimLayerBlending(s.alpha);
engine.drawMesh(mesh);

View File

@ -34,7 +34,8 @@ public:
virtual ~LayerDim();
virtual const char* getTypeId() const { return "LayerDim"; }
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
bool useIdentityTransform) const;
virtual bool isOpaque() const { return false; }
virtual bool isSecure() const { return false; }
virtual bool isFixedSize() const { return true; }

View File

@ -190,7 +190,7 @@ SurfaceFlinger::~SurfaceFlinger()
eglTerminate(display);
}
void SurfaceFlinger::binderDied(const wp<IBinder>& who)
void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
{
// the window manager died on us. prepare its eulogy.
@ -593,12 +593,12 @@ void SurfaceFlinger::signalRefresh() {
}
status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t flags) {
nsecs_t reltime, uint32_t /* flags */) {
return mEventQueue.postMessage(msg, reltime);
}
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t flags) {
nsecs_t reltime, uint32_t /* flags */) {
status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR) {
msg->wait();
@ -1710,7 +1710,7 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
return status_t(index);
}
uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) {
uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
return android_atomic_release_load(&mTransactionFlags);
}
@ -2220,8 +2220,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
return NO_ERROR;
}
void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
String8& result) const
void SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
size_t& /* index */, String8& result) const
{
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
@ -2259,7 +2259,7 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
}
void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
String8& result)
String8& /* result */)
{
String8 name;
if (index < args.size()) {
@ -2664,7 +2664,7 @@ class GraphicProducerWrapper : public BBinder, public MessageHandler {
* data and reply Parcel and forward them to the calling thread.
*/
virtual status_t transact(uint32_t code,
const Parcel& data, Parcel* reply, uint32_t flags) {
const Parcel& data, Parcel* reply, uint32_t /* flags */) {
this->code = code;
this->data = &data;
this->reply = reply;
@ -2718,7 +2718,8 @@ public:
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ) {
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform) {
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
@ -2744,16 +2745,19 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<IGraphicBufferProducer> producer;
uint32_t reqWidth, reqHeight;
uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform;
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)
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform)
: flinger(flinger), display(display), producer(producer),
reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
result(PERMISSION_DENIED)
{
}
@ -2763,8 +2767,9 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
virtual bool handler() {
Mutex::Autolock _l(flinger->mStateLock);
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
result = flinger->captureScreenImplLocked(hw,
producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
result = flinger->captureScreenImplLocked(hw, producer,
reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform);
static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
return true;
}
@ -2786,7 +2791,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
// which does the marshaling work forwards to our "fake remote" above.
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
reqWidth, reqHeight, minLayerZ, maxLayerZ);
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
@ -2800,7 +2805,7 @@ void SurfaceFlinger::renderScreenImplLocked(
const sp<const DisplayDevice>& hw,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool yswap)
bool yswap, bool useIdentityTransform)
{
ATRACE_CALL();
RenderEngine& engine(getRenderEngine());
@ -2829,7 +2834,7 @@ void SurfaceFlinger::renderScreenImplLocked(
if (state.z >= minLayerZ && state.z <= maxLayerZ) {
if (layer->isVisible()) {
if (filtering) layer->setFiltering(true);
layer->draw(hw);
layer->draw(hw, useIdentityTransform);
if (filtering) layer->setFiltering(false);
}
}
@ -2846,7 +2851,8 @@ 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,
bool useIdentityTransform)
{
ATRACE_CALL();
@ -2900,7 +2906,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(
// an EGLSurface and therefore we're not
// dependent on the context's EGLConfig.
renderScreenImplLocked(hw, reqWidth, reqHeight,
minLayerZ, maxLayerZ, true);
minLayerZ, maxLayerZ, true, useIdentityTransform);
// Create a sync point and wait on it, so we know the buffer is
// ready before we pass it along. We can't trivially call glFlush(),

View File

@ -203,7 +203,8 @@ private:
virtual status_t captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ);
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform);
// called when screen needs to turn off
virtual void blank(const sp<IBinder>& display);
// called when screen is turning back on
@ -307,13 +308,14 @@ private:
const sp<const DisplayDevice>& hw,
uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool yswap);
bool yswap, bool useIdentityTransform);
status_t 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,
bool useIdentityTransform);
/* ------------------------------------------------------------------------
* EGL