Skip to content

Commit 830d083

Browse files
author
Jamie Gennis
committed
SurfaceFlinger: screenshots w/ protected buffers
This change modifies SurfaceFlinger's screenshot behavior when a layer with a protected buffer is visible. The previous behavior was to simply fail the screenshot. The new behavior is to render the screenshot using a placeholder texture where the protected buffer would have been. Change-Id: I5e50cb2f3b31b2ea81cfe291c9b4a42e9ee71874
1 parent ba8ecd2 commit 830d083

File tree

3 files changed

+38
-30
lines changed

3 files changed

+38
-30
lines changed

services/surfaceflinger/Layer.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -280,20 +280,29 @@ void Layer::onDraw(const Region& clip) const
280280
return;
281281
}
282282

283-
const GLenum target = GL_TEXTURE_EXTERNAL_OES;
284-
glBindTexture(target, mTextureName);
285-
if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
286-
// TODO: we could be more subtle with isFixedSize()
287-
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
288-
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
283+
GLenum target = GL_TEXTURE_EXTERNAL_OES;
284+
if (!isProtected()) {
285+
glBindTexture(target, mTextureName);
286+
if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
287+
// TODO: we could be more subtle with isFixedSize()
288+
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
289+
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
290+
} else {
291+
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
292+
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
293+
}
294+
glEnable(target);
295+
glMatrixMode(GL_TEXTURE);
296+
glLoadMatrixf(mTextureMatrix);
297+
glMatrixMode(GL_MODELVIEW);
289298
} else {
290-
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
291-
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
299+
target = GL_TEXTURE_2D;
300+
glBindTexture(target, mFlinger->getProtectedTexName());
301+
glEnable(target);
302+
glMatrixMode(GL_TEXTURE);
303+
glLoadIdentity();
304+
glMatrixMode(GL_MODELVIEW);
292305
}
293-
glEnable(target);
294-
glMatrixMode(GL_TEXTURE);
295-
glLoadMatrixf(mTextureMatrix);
296-
glMatrixMode(GL_MODELVIEW);
297306

298307
drawWithOpenGL(clip);
299308

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,25 @@ status_t SurfaceFlinger::readyToRun()
275275

276276
const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
277277
const uint16_t g1 = pack565(0x17,0x2f,0x17);
278-
const uint16_t textureData[4] = { g0, g1, g1, g0 };
278+
const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
279279
glGenTextures(1, &mWormholeTexName);
280280
glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
281281
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
282282
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
283283
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
284284
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
285285
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
286-
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
286+
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
287+
288+
const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
289+
glGenTextures(1, &mProtectedTexName);
290+
glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
291+
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
292+
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
293+
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
294+
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
295+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
296+
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
287297

288298
glViewport(0, 0, w, h);
289299
glMatrixMode(GL_PROJECTION);
@@ -2255,22 +2265,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
22552265
if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
22562266
return BAD_VALUE;
22572267

2258-
// make sure none of the layers are protected
2259-
const LayerVector& layers(mDrawingState.layersSortedByZ);
2260-
const size_t count = layers.size();
2261-
for (size_t i=0 ; i<count ; ++i) {
2262-
const sp<LayerBase>& layer(layers[i]);
2263-
const uint32_t flags = layer->drawingState().flags;
2264-
if (!(flags & ISurfaceComposer::eLayerHidden)) {
2265-
const uint32_t z = layer->drawingState().z;
2266-
if (z >= minLayerZ && z <= maxLayerZ) {
2267-
if (layer->isProtected()) {
2268-
return INVALID_OPERATION;
2269-
}
2270-
}
2271-
}
2272-
}
2273-
22742268
if (!GLExtensions::getInstance().haveFramebufferObject())
22752269
return INVALID_OPERATION;
22762270

@@ -2320,6 +2314,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
23202314
glClearColor(0,0,0,1);
23212315
glClear(GL_COLOR_BUFFER_BIT);
23222316

2317+
const LayerVector& layers(mDrawingState.layersSortedByZ);
2318+
const size_t count = layers.size();
23232319
for (size_t i=0 ; i<count ; ++i) {
23242320
const sp<LayerBase>& layer(layers[i]);
23252321
const uint32_t flags = layer->drawingState().flags;

services/surfaceflinger/SurfaceFlinger.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ class SurfaceFlinger :
192192

193193
sp<Layer> getLayer(const sp<ISurface>& sur) const;
194194

195+
GLuint getProtectedTexName() const { return mProtectedTexName; }
196+
195197
private:
196198
// DeathRecipient interface
197199
virtual void binderDied(const wp<IBinder>& who);
@@ -349,6 +351,7 @@ class SurfaceFlinger :
349351
sp<IMemoryHeap> mServerHeap;
350352
surface_flinger_cblk_t* mServerCblk;
351353
GLuint mWormholeTexName;
354+
GLuint mProtectedTexName;
352355
nsecs_t mBootTime;
353356

354357
// Can only accessed from the main thread, these members

0 commit comments

Comments
 (0)