summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.cpp5
-rw-r--r--services/surfaceflinger/Layer.cpp19
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp224
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h33
-rw-r--r--services/surfaceflinger/tests/resize/resize.cpp8
-rw-r--r--services/surfaceflinger/tests/surface/surface.cpp4
6 files changed, 157 insertions, 136 deletions
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index a774841..33125c4 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -103,6 +103,11 @@ void DisplayHardware::init(uint32_t dpy)
{
mNativeWindow = new FramebufferNativeWindow();
framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
+ if (!fbDev) {
+ LOGE("Display subsystem failed to initialize. check logs. exiting...");
+ exit(0);
+ }
+
mDpiX = mNativeWindow->xdpi;
mDpiY = mNativeWindow->ydpi;
mRefreshRate = fbDev->fps;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2bab6a8..35e29a6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -101,9 +101,8 @@ Layer::~Layer()
}
void Layer::onFrameQueued() {
- if (android_atomic_or(1, &mQueuedFrames) == 0) {
- mFlinger->signalEvent();
- }
+ android_atomic_inc(&mQueuedFrames);
+ mFlinger->signalEvent();
}
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
@@ -406,20 +405,18 @@ bool Layer::isCropped() const {
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
- if (android_atomic_and(0, &mQueuedFrames)) {
+ if (mQueuedFrames > 0) {
+ // signal another event if we have more frames pending
+ if (android_atomic_dec(&mQueuedFrames) > 1) {
+ mFlinger->signalEvent();
+ }
+
if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
// something happened!
recomputeVisibleRegions = true;
return;
}
- // signal another event if we have more frames waiting
- if (mSurfaceTexture->getQueuedCount()) {
- if (android_atomic_or(1, &mQueuedFrames) == 0) {
- mFlinger->signalEvent();
- }
- }
-
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
mSurfaceTexture->getTransformMatrix(mTextureMatrix);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 97edfee..cccab4a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -32,6 +32,7 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
+#include <binder/PermissionCache.h>
#include <utils/String8.h>
#include <utils/String16.h>
@@ -67,17 +68,19 @@
namespace android {
// ---------------------------------------------------------------------------
+const String16 sHardwareTest("android.permission.HARDWARE_TEST");
+const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
+const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
+const String16 sDump("android.permission.DUMP");
+
+// ---------------------------------------------------------------------------
+
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false),
mTransactionFlags(0),
- mTransactionCount(0),
mResizeTransationPending(false),
mLayersRemoved(false),
mBootTime(systemTime()),
- mHardwareTest("android.permission.HARDWARE_TEST"),
- mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
- mReadFramebuffer("android.permission.READ_FRAME_BUFFER"),
- mDump("android.permission.DUMP"),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
mDeferReleaseConsole(false),
@@ -160,9 +163,34 @@ void SurfaceFlinger::bootFinished()
const nsecs_t duration = now - mBootTime;
LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
mBootFinished = true;
+
+ // wait patiently for the window manager death
+ const String16 name("window");
+ sp<IBinder> window(defaultServiceManager()->getService(name));
+ if (window != 0) {
+ window->linkToDeath(this);
+ }
+
+ // stop boot animation
property_set("ctl.stop", "bootanim");
}
+void SurfaceFlinger::binderDied(const wp<IBinder>& who)
+{
+ // the window manager died on us. prepare its eulogy.
+
+ // unfreeze the screen in case it was... frozen
+ mFreezeDisplayTime = 0;
+ mFreezeCount = 0;
+ mFreezeDisplay = false;
+
+ // reset screen orientation
+ setOrientation(0, eOrientationDefault, 0);
+
+ // restart the boot-animation
+ property_set("ctl.start", "bootanim");
+}
+
void SurfaceFlinger::onFirstRef()
{
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
@@ -381,13 +409,11 @@ bool SurfaceFlinger::threadLoop()
handleConsoleEvents();
}
- if (LIKELY(mTransactionCount == 0)) {
- // if we're in a global transaction, don't do anything.
- const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
- uint32_t transactionFlags = peekTransactionFlags(mask);
- if (LIKELY(transactionFlags)) {
- handleTransaction(transactionFlags);
- }
+ // if we're in a global transaction, don't do anything.
+ const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+ uint32_t transactionFlags = peekTransactionFlags(mask);
+ if (UNLIKELY(transactionFlags)) {
+ handleTransaction(transactionFlags);
}
// post surfaces (if needed)
@@ -1172,28 +1198,33 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
return old;
}
-void SurfaceFlinger::openGlobalTransaction()
-{
- android_atomic_inc(&mTransactionCount);
-}
-void SurfaceFlinger::closeGlobalTransaction()
-{
- if (android_atomic_dec(&mTransactionCount) == 1) {
- signalEvent();
+void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state) {
+ Mutex::Autolock _l(mStateLock);
- // if there is a transaction with a resize, wait for it to
- // take effect before returning.
- Mutex::Autolock _l(mStateLock);
- while (mResizeTransationPending) {
- status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
- if (CC_UNLIKELY(err != NO_ERROR)) {
- // just in case something goes wrong in SF, return to the
- // called after a few seconds.
- LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
- mResizeTransationPending = false;
- break;
- }
+ uint32_t flags = 0;
+ const size_t count = state.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const ComposerState& s(state[i]);
+ sp<Client> client( static_cast<Client *>(s.client.get()) );
+ flags |= setClientStateLocked(client, s.state);
+ }
+ if (flags) {
+ setTransactionFlags(flags);
+ }
+
+ signalEvent();
+
+ // if there is a transaction with a resize, wait for it to
+ // take effect before returning.
+ while (mResizeTransationPending) {
+ status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
+ if (CC_UNLIKELY(err != NO_ERROR)) {
+ // just in case something goes wrong in SF, return to the
+ // called after a few seconds.
+ LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
+ mResizeTransationPending = false;
+ break;
}
}
}
@@ -1389,60 +1420,52 @@ status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
return err;
}
-status_t SurfaceFlinger::setClientState(
+uint32_t SurfaceFlinger::setClientStateLocked(
const sp<Client>& client,
- int32_t count,
- const layer_state_t* states)
+ const layer_state_t& s)
{
- Mutex::Autolock _l(mStateLock);
uint32_t flags = 0;
- for (int i=0 ; i<count ; i++) {
- const layer_state_t& s(states[i]);
- sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
- if (layer != 0) {
- const uint32_t what = s.what;
- if (what & ePositionChanged) {
- if (layer->setPosition(s.x, s.y))
- flags |= eTraversalNeeded;
- }
- if (what & eLayerChanged) {
- ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
- if (layer->setLayer(s.z)) {
- mCurrentState.layersSortedByZ.removeAt(idx);
- mCurrentState.layersSortedByZ.add(layer);
- // we need traversal (state changed)
- // AND transaction (list changed)
- flags |= eTransactionNeeded|eTraversalNeeded;
- }
- }
- if (what & eSizeChanged) {
- if (layer->setSize(s.w, s.h)) {
- flags |= eTraversalNeeded;
- mResizeTransationPending = true;
- }
- }
- if (what & eAlphaChanged) {
- if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
- flags |= eTraversalNeeded;
- }
- if (what & eMatrixChanged) {
- if (layer->setMatrix(s.matrix))
- flags |= eTraversalNeeded;
- }
- if (what & eTransparentRegionChanged) {
- if (layer->setTransparentRegionHint(s.transparentRegion))
- flags |= eTraversalNeeded;
+ sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
+ if (layer != 0) {
+ const uint32_t what = s.what;
+ if (what & ePositionChanged) {
+ if (layer->setPosition(s.x, s.y))
+ flags |= eTraversalNeeded;
+ }
+ if (what & eLayerChanged) {
+ ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
+ if (layer->setLayer(s.z)) {
+ mCurrentState.layersSortedByZ.removeAt(idx);
+ mCurrentState.layersSortedByZ.add(layer);
+ // we need traversal (state changed)
+ // AND transaction (list changed)
+ flags |= eTransactionNeeded|eTraversalNeeded;
}
- if (what & eVisibilityChanged) {
- if (layer->setFlags(s.flags, s.mask))
- flags |= eTraversalNeeded;
+ }
+ if (what & eSizeChanged) {
+ if (layer->setSize(s.w, s.h)) {
+ flags |= eTraversalNeeded;
+ mResizeTransationPending = true;
}
}
+ if (what & eAlphaChanged) {
+ if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
+ flags |= eTraversalNeeded;
+ }
+ if (what & eMatrixChanged) {
+ if (layer->setMatrix(s.matrix))
+ flags |= eTraversalNeeded;
+ }
+ if (what & eTransparentRegionChanged) {
+ if (layer->setTransparentRegionHint(s.transparentRegion))
+ flags |= eTraversalNeeded;
+ }
+ if (what & eVisibilityChanged) {
+ if (layer->setFlags(s.flags, s.mask))
+ flags |= eTraversalNeeded;
+ }
}
- if (flags) {
- setTransactionFlags(flags);
- }
- return NO_ERROR;
+ return flags;
}
void SurfaceFlinger::screenReleased(int dpy)
@@ -1464,7 +1487,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
const size_t SIZE = 4096;
char buffer[SIZE];
String8 result;
- if (!mDump.checkCalling()) {
+
+ if (!PermissionCache::checkCallingPermission(sDump)) {
snprintf(buffer, SIZE, "Permission Denial: "
"can't dump SurfaceFlinger from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(),
@@ -1583,8 +1607,7 @@ status_t SurfaceFlinger::onTransact(
{
switch (code) {
case CREATE_CONNECTION:
- case OPEN_GLOBAL_TRANSACTION:
- case CLOSE_GLOBAL_TRANSACTION:
+ case SET_TRANSACTION_STATE:
case SET_ORIENTATION:
case FREEZE_DISPLAY:
case UNFREEZE_DISPLAY:
@@ -1596,7 +1619,8 @@ status_t SurfaceFlinger::onTransact(
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
- if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
+ if ((uid != AID_GRAPHICS) &&
+ !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
LOGE("Permission Denial: "
"can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
@@ -1609,7 +1633,8 @@ status_t SurfaceFlinger::onTransact(
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
- if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) {
+ if ((uid != AID_GRAPHICS) &&
+ !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
LOGE("Permission Denial: "
"can't read framebuffer pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
@@ -1621,7 +1646,7 @@ status_t SurfaceFlinger::onTransact(
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- if (UNLIKELY(!mHardwareTest.checkCalling())) {
+ if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
@@ -1799,10 +1824,10 @@ status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
const GLfloat h = hw_h - (hw_h * v);
const GLfloat x = (hw_w - w) * 0.5f;
const GLfloat y = (hw_h - h) * 0.5f;
- vtx[0] = x; vtx[1] = y;
- vtx[2] = x; vtx[3] = y + h;
- vtx[4] = x + w; vtx[5] = y + h;
- vtx[6] = x + w; vtx[7] = y;
+ vtx[0] = x; vtx[1] = y + h;
+ vtx[2] = x; vtx[3] = y;
+ vtx[4] = x + w; vtx[5] = y;
+ vtx[6] = x + w; vtx[7] = y + h;
}
};
@@ -1817,10 +1842,10 @@ status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
const GLfloat h = 1.0f;
const GLfloat x = (hw_w - w) * 0.5f;
const GLfloat y = (hw_h - h) * 0.5f;
- vtx[0] = x; vtx[1] = y;
- vtx[2] = x; vtx[3] = y + h;
- vtx[4] = x + w; vtx[5] = y + h;
- vtx[6] = x + w; vtx[7] = y;
+ vtx[0] = x; vtx[1] = y + h;
+ vtx[2] = x; vtx[3] = y;
+ vtx[4] = x + w; vtx[5] = y;
+ vtx[6] = x + w; vtx[7] = y + h;
}
};
@@ -2404,8 +2429,7 @@ status_t Client::onTransact(
const int self_pid = getpid();
if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
// we're called from a different process, do the real check
- if (!checkCallingPermission(
- String16("android.permission.ACCESS_SURFACE_FLINGER")))
+ if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
{
LOGE("Permission Denial: "
"can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
@@ -2463,9 +2487,6 @@ sp<ISurface> Client::createSurface(
status_t Client::destroySurface(SurfaceID sid) {
return mFlinger->removeSurface(this, sid);
}
-status_t Client::setState(int32_t count, const layer_state_t* states) {
- return mFlinger->setClientState(this, count, states);
-}
// ---------------------------------------------------------------------------
@@ -2474,11 +2495,14 @@ GraphicBufferAlloc::GraphicBufferAlloc() {}
GraphicBufferAlloc::~GraphicBufferAlloc() {}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) {
+ PixelFormat format, uint32_t usage, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
status_t err = graphicBuffer->initCheck();
+ *error = err;
if (err != 0 || graphicBuffer->handle == 0) {
- GraphicBuffer::dumpAllocationsToSystemLog();
+ if (err == NO_MEMORY) {
+ GraphicBuffer::dumpAllocationsToSystemLog();
+ }
LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
"failed (%s), handle=%p",
w, h, strerror(-err), graphicBuffer->handle);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index af1ef04..15661f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -20,21 +20,20 @@
#include <stdint.h>
#include <sys/types.h>
-#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
+#include <utils/SortedVector.h>
+#include <utils/threads.h>
-#include <binder/IMemory.h>
-#include <binder/Permission.h>
#include <binder/BinderService.h>
+#include <binder/IMemory.h>
#include <ui/PixelFormat.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
#include "Barrier.h"
#include "Layer.h"
@@ -71,14 +70,12 @@ public:
sp<LayerBaseClient> getLayerUser(int32_t i) const;
private:
-
// ISurfaceComposerClient interface
virtual sp<ISurface> createSurface(
surface_data_t* params, const String8& name,
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
uint32_t flags);
virtual status_t destroySurface(SurfaceID surfaceId);
- virtual status_t setState(int32_t count, const layer_state_t* states);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
@@ -99,7 +96,7 @@ public:
GraphicBufferAlloc();
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage);
+ PixelFormat format, uint32_t usage, status_t* error);
};
// ---------------------------------------------------------------------------
@@ -150,6 +147,7 @@ enum {
class SurfaceFlinger :
public BinderService<SurfaceFlinger>,
public BnSurfaceComposer,
+ public IBinder::DeathRecipient,
protected Thread
{
public:
@@ -169,8 +167,7 @@ public:
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
virtual sp<IMemoryHeap> getCblk() const;
virtual void bootFinished();
- virtual void openGlobalTransaction();
- virtual void closeGlobalTransaction();
+ virtual void setTransactionState(const Vector<ComposerState>& state);
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags);
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
@@ -197,6 +194,10 @@ public:
sp<Layer> getLayer(const sp<ISurface>& sur) const;
private:
+ // DeathRecipient interface
+ virtual void binderDied(const wp<IBinder>& who);
+
+private:
friend class Client;
friend class LayerBase;
friend class LayerBaseClient;
@@ -221,8 +222,7 @@ private:
status_t removeSurface(const sp<Client>& client, SurfaceID sid);
status_t destroySurface(const wp<LayerBaseClient>& layer);
- status_t setClientState(const sp<Client>& client,
- int32_t count, const layer_state_t* states);
+ uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s);
class LayerVector : public SortedVector< sp<LayerBase> > {
public:
@@ -338,7 +338,6 @@ private:
mutable Mutex mStateLock;
State mCurrentState;
volatile int32_t mTransactionFlags;
- volatile int32_t mTransactionCount;
Condition mTransactionCV;
SortedVector< sp<LayerBase> > mLayerPurgatory;
bool mResizeTransationPending;
@@ -353,11 +352,7 @@ private:
surface_flinger_cblk_t* mServerCblk;
GLuint mWormholeTexName;
nsecs_t mBootTime;
- Permission mHardwareTest;
- Permission mAccessSurfaceFlinger;
- Permission mReadFramebuffer;
- Permission mDump;
-
+
// Can only accessed from the main thread, these members
// don't need synchronization
State mDrawingState;
diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
index 18c54b3..56b2a8f 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -43,9 +43,9 @@ int main(int argc, char** argv)
PIXEL_FORMAT_RGB_565);
- client->openTransaction();
+ SurfaceComposerClient::openGlobalTransaction();
surface->setLayer(100000);
- client->closeTransaction();
+ SurfaceComposerClient::closeGlobalTransaction();
Surface::SurfaceInfo info;
surface->lock(&info);
@@ -57,9 +57,9 @@ int main(int argc, char** argv)
android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h);
surface->unlockAndPost();
- client->openTransaction();
+ SurfaceComposerClient::openGlobalTransaction();
surface->setSize(320, 240);
- client->closeTransaction();
+ SurfaceComposerClient::closeGlobalTransaction();
IPCThreadState::self()->joinThreadPool();
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index 5265f91..8e1c3fe 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -39,9 +39,9 @@ int main(int argc, char** argv)
sp<SurfaceControl> surfaceControl = client->createSurface(
getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565);
- client->openTransaction();
+ SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(100000);
- client->closeTransaction();
+ SurfaceComposerClient::closeGlobalTransaction();
// pretend it went cross-process
Parcel parcel;