summaryrefslogtreecommitdiffstats
path: root/libs/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp83
1 files changed, 54 insertions, 29 deletions
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index c2adf07..7a277fe 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -62,6 +62,13 @@
#include "GPUHardware/GPUHardware.h"
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
#define DISPLAY_COUNT 1
namespace android {
@@ -185,7 +192,6 @@ SurfaceFlinger::SurfaceFlinger()
mDebugCpu(0),
mDebugFps(0),
mDebugBackground(0),
- mDebugNoBootAnimation(0),
mSyncObject(),
mDeplayedTransactionPending(0),
mConsoleSignals(0),
@@ -208,14 +214,11 @@ void SurfaceFlinger::init()
mDebugBackground = atoi(value);
property_get("debug.sf.showfps", value, "0");
mDebugFps = atoi(value);
- property_get("debug.sf.nobootanimation", value, "0");
- mDebugNoBootAnimation = atoi(value);
LOGI_IF(mDebugRegion, "showupdates enabled");
LOGI_IF(mDebugCpu, "showcpu enabled");
LOGI_IF(mDebugBackground, "showbackground enabled");
LOGI_IF(mDebugFps, "showfps enabled");
- LOGI_IF(mDebugNoBootAnimation, "boot animation disabled");
}
SurfaceFlinger::~SurfaceFlinger()
@@ -242,6 +245,9 @@ sp<IMemory> SurfaceFlinger::getCblk() const
status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
gpu_info_t* gpu)
{
+ if (mGPU == 0)
+ return INVALID_OPERATION;
+
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
status_t err = mGPU->request(pid, callback, gpu);
@@ -250,6 +256,9 @@ status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
status_t SurfaceFlinger::revokeGPU()
{
+ if (mGPU == 0)
+ return INVALID_OPERATION;
+
return mGPU->friendlyRevoke();
}
@@ -319,11 +328,8 @@ void SurfaceFlinger::bootFinished()
{
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
- LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
- if (mBootAnimation != 0) {
- mBootAnimation->requestExit();
- mBootAnimation.clear();
- }
+ LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
+ property_set("ctl.stop", "bootanim");
}
void SurfaceFlinger::onFirstRef()
@@ -451,10 +457,10 @@ status_t SurfaceFlinger::readyToRun()
if (mDebugCpu)
mCpuGauge = new CPUGauge(this, ms2ns(500));
- // the boot animation!
- if (mDebugNoBootAnimation == false)
- mBootAnimation = new BootAnimation(this);
-
+
+ // start boot animation
+ property_set("ctl.start", "bootanim");
+
return NO_ERROR;
}
@@ -686,9 +692,14 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
// some layers might have been removed, so
// we need to update the regions they're exposing.
- size_t c = mRemovedLayers.size();
+ const SortedVector<LayerBase*>& removedLayers(mRemovedLayers);
+ size_t c = removedLayers.size();
if (c) {
mVisibleRegionsDirty = true;
+ while (c--) {
+ mDirtyRegionRemovedLayer.orSelf(
+ removedLayers[c]->visibleRegionScreen);
+ }
}
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
@@ -728,17 +739,15 @@ void SurfaceFlinger::computeVisibleRegions(
layer->validateVisibility(planeTransform);
// start with the whole surface at its current location
- const Layer::State& s = layer->drawingState();
- const Rect bounds(layer->visibleBounds());
+ const Layer::State& s(layer->drawingState());
// handle hidden surfaces by setting the visible region to empty
Region opaqueRegion;
Region visibleRegion;
Region coveredRegion;
- if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) {
- visibleRegion.clear();
- } else {
+ if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
const bool translucent = layer->needsBlending();
+ const Rect bounds(layer->visibleBounds());
visibleRegion.set(bounds);
coveredRegion = visibleRegion;
@@ -766,10 +775,11 @@ void SurfaceFlinger::computeVisibleRegions(
dirty.orSelf(layer->visibleRegionScreen);
layer->contentDirty = false;
} else {
- // compute the exposed region
- // dirty = what's visible now - what's wasn't covered before
- // = what's visible now & what's was covered before
- dirty = visibleRegion.intersect(layer->coveredRegionScreen);
+ /* compute the exposed region:
+ * exposed = what's VISIBLE and NOT COVERED now
+ * but was COVERED before
+ */
+ dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen;
}
dirty.subtractSelf(aboveOpaqueLayers);
@@ -778,18 +788,22 @@ void SurfaceFlinger::computeVisibleRegions(
// updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
aboveOpaqueLayers.orSelf(opaqueRegion);
- aboveCoveredLayers.orSelf(bounds);
+ aboveCoveredLayers.orSelf(visibleRegion);
// Store the visible region is screen space
layer->setVisibleRegion(visibleRegion);
layer->setCoveredRegion(coveredRegion);
- // If a secure layer is partially visible, lockdown the screen!
+ // If a secure layer is partially visible, lock-down the screen!
if (layer->isSecure() && !visibleRegion.isEmpty()) {
secureFrameBuffer = true;
}
}
+ // invalidate the areas where a layer was removed
+ dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
+ mDirtyRegionRemovedLayer.clear();
+
mSecureFrameBuffer = secureFrameBuffer;
opaqueRegion = aboveOpaqueLayers;
}
@@ -1230,6 +1244,13 @@ sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
{
LayerBaseClient* layer = 0;
sp<LayerBaseClient::Surface> surfaceHandle;
+
+ if (int32_t(w|h) < 0) {
+ LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
+ int(w), int(h));
+ return surfaceHandle;
+ }
+
Mutex::Autolock _l(mStateLock);
Client* const c = mClientsMap.valueFor(clientId);
if (UNLIKELY(!c)) {
@@ -1538,13 +1559,13 @@ status_t SurfaceFlinger::onTransact(
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid)) {
+ if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
// we're called from a different process, do the real check
if (!checkCallingPermission(
String16("android.permission.ACCESS_SURFACE_FLINGER")))
{
- const int uid = ipc->getCallingUid();
LOGE("Permission Denial: "
"can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
@@ -1601,10 +1622,14 @@ status_t SurfaceFlinger::onTransact(
}
return NO_ERROR;
case 1005: // ask GPU revoke
- mGPU->friendlyRevoke();
+ if (mGPU != 0) {
+ mGPU->friendlyRevoke();
+ }
return NO_ERROR;
case 1006: // revoke GPU
- mGPU->unconditionalRevoke();
+ if (mGPU != 0) {
+ mGPU->unconditionalRevoke();
+ }
return NO_ERROR;
case 1007: // set mFreezeCount
mFreezeCount = data.readInt32();