diff options
Diffstat (limited to 'libs/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 83 |
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(); |