summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/inputflinger/InputDispatcher.cpp25
-rw-r--r--services/inputflinger/InputWindow.h6
-rw-r--r--services/sensorservice/SensorService.cpp111
-rw-r--r--services/sensorservice/SensorService.h21
-rw-r--r--services/surfaceflinger/Android.mk6
-rw-r--r--services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/FramebufferSurface.h2
-rw-r--r--services/surfaceflinger/Layer.cpp26
-rw-r--r--services/surfaceflinger/Layer.h3
-rw-r--r--services/surfaceflinger/LayerDim.h5
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.cpp4
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp28
13 files changed, 166 insertions, 76 deletions
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 02fb6f0..603836a 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -477,7 +477,6 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display
const InputWindowInfo* windowInfo = windowHandle->getInfo();
if (windowInfo->displayId == displayId) {
int32_t flags = windowInfo->layoutParamsFlags;
- int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
if (windowInfo->visible) {
if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
@@ -489,11 +488,6 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display
}
}
}
-
- if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
- // Error window is on top but not visible, so touch is dropped.
- return NULL;
- }
}
}
return NULL;
@@ -1190,7 +1184,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
int32_t y = int32_t(entry->pointerCoords[pointerIndex].
getAxisValue(AMOTION_EVENT_AXIS_Y));
sp<InputWindowHandle> newTouchedWindowHandle;
- sp<InputWindowHandle> topErrorWindowHandle;
bool isTouchModal = false;
// Traverse windows from front to back to find touched window and outside targets.
@@ -1202,13 +1195,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
continue; // wrong display
}
- int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
- if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
- if (topErrorWindowHandle == NULL) {
- topErrorWindowHandle = windowHandle;
- }
- }
-
int32_t flags = windowInfo->layoutParamsFlags;
if (windowInfo->visible) {
if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
@@ -1233,17 +1219,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
}
}
- // If there is an error window but it is not taking focus (typically because
- // it is invisible) then wait for it. Any other focused window may in
- // fact be in ANR state.
- if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- NULL, NULL, nextWakeupTime,
- "Waiting because a system error window is about to be displayed.");
- injectionPermission = INJECTION_PERMISSION_UNKNOWN;
- goto Unresponsive;
- }
-
// Figure out whether splitting will be allowed for this window.
if (newTouchedWindowHandle != NULL
&& newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
diff --git a/services/inputflinger/InputWindow.h b/services/inputflinger/InputWindow.h
index 5879c84..42457ce 100644
--- a/services/inputflinger/InputWindow.h
+++ b/services/inputflinger/InputWindow.h
@@ -64,11 +64,6 @@ struct InputWindowInfo {
FLAG_NEEDS_MENU_KEY = 0x40000000,
};
- // Private Window flags from WindowManager.LayoutParams
- enum {
- PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100,
- };
-
// Window types from WindowManager.LayoutParams
enum {
FIRST_APPLICATION_WINDOW = 1,
@@ -119,7 +114,6 @@ struct InputWindowInfo {
sp<InputChannel> inputChannel;
String8 name;
int32_t layoutParamsFlags;
- int32_t layoutParamsPrivateFlags;
int32_t layoutParamsType;
nsecs_t dispatchingTimeout;
int32_t frameLeft;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index dc8fa64..c316ef6 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -191,6 +191,8 @@ void SensorService::onFirstRef()
mSensorEventScratch = new sensors_event_t[minBufferSize];
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
+ mAckReceiver = new SensorEventAckReceiver(this);
+ mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
mInitCheck = NO_ERROR;
run("SensorService", PRIORITY_URGENT_DISPLAY);
}
@@ -386,8 +388,6 @@ bool SensorService::threadLoop()
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
- SensorEventAckReceiver sender(this);
- sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
const int halVersion = device.getHalDeviceVersion();
do {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
@@ -408,16 +408,7 @@ bool SensorService::threadLoop()
// result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
// cleanup. So copy all the strongPointers to a vector before the lock is acquired.
SortedVector< sp<SensorEventConnection> > activeConnections;
- {
- Mutex::Autolock _l(mLock);
- for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
- sp<SensorEventConnection> connection(mActiveConnections[i].promote());
- if (connection != 0) {
- activeConnections.add(connection);
- }
- }
- }
-
+ populateActiveConnections(&activeConnections);
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
// rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
@@ -433,8 +424,7 @@ bool SensorService::threadLoop()
}
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
- mWakeLockAcquired = true;
+ setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);
@@ -522,8 +512,7 @@ bool SensorService::threadLoop()
}
if (mWakeLockAcquired && !needsWakeLock) {
- release_wake_lock(WAKE_LOCK_NAME);
- mWakeLockAcquired = false;
+ setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
@@ -536,11 +525,52 @@ sp<Looper> SensorService::getLooper() const {
return mLooper;
}
+void SensorService::resetAllWakeLockRefCounts() {
+ SortedVector< sp<SensorEventConnection> > activeConnections;
+ populateActiveConnections(&activeConnections);
+ {
+ Mutex::Autolock _l(mLock);
+ for (size_t i=0 ; i < activeConnections.size(); ++i) {
+ if (activeConnections[i] != 0) {
+ activeConnections[i]->resetWakeLockRefCount();
+ }
+ }
+ setWakeLockAcquiredLocked(false);
+ }
+}
+
+void SensorService::setWakeLockAcquiredLocked(bool acquire) {
+ if (acquire) {
+ if (!mWakeLockAcquired) {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+ mWakeLockAcquired = true;
+ }
+ mLooper->wake();
+ } else {
+ if (mWakeLockAcquired) {
+ release_wake_lock(WAKE_LOCK_NAME);
+ mWakeLockAcquired = false;
+ }
+ }
+}
+
+
+bool SensorService::isWakeLockAcquired() {
+ Mutex::Autolock _l(mLock);
+ return mWakeLockAcquired;
+}
+
bool SensorService::SensorEventAckReceiver::threadLoop() {
ALOGD("new thread SensorEventAckReceiver");
+ sp<Looper> looper = mService->getLooper();
do {
- sp<Looper> looper = mService->getLooper();
- looper->pollOnce(-1);
+ bool wakeLockAcquired = mService->isWakeLockAcquired();
+ int timeout = -1;
+ if (wakeLockAcquired) timeout = 5000;
+ int ret = looper->pollOnce(timeout);
+ if (ret == ALOOPER_POLL_TIMEOUT) {
+ mService->resetAllWakeLockRefCounts();
+ }
} while(!Thread::exitPending());
return false;
}
@@ -714,10 +744,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
sensors_event_t& event(mLastEventSeen.editValueFor(handle));
if (event.version == sizeof(sensors_event_t)) {
if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
- mWakeLockAcquired = true;
- ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s",
- WAKE_LOCK_NAME);
+ setWakeLockAcquiredLocked(true);
}
connection->sendEvents(&event, 1, NULL);
if (!connection->needsWakeLock() && mWakeLockAcquired) {
@@ -922,8 +949,26 @@ void SensorService::checkWakeLockStateLocked() {
}
}
if (releaseLock) {
- release_wake_lock(WAKE_LOCK_NAME);
- mWakeLockAcquired = false;
+ setWakeLockAcquiredLocked(false);
+ }
+}
+
+void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
+ Mutex::Autolock _l(mLock);
+ connection->writeToSocketFromCache();
+ if (connection->needsWakeLock()) {
+ setWakeLockAcquiredLocked(true);
+ }
+}
+
+void SensorService::populateActiveConnections(
+ SortedVector< sp<SensorEventConnection> >* activeConnections) {
+ Mutex::Autolock _l(mLock);
+ for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
+ sp<SensorEventConnection> connection(mActiveConnections[i].promote());
+ if (connection != 0) {
+ activeConnections->add(connection);
+ }
}
}
@@ -1013,6 +1058,11 @@ bool SensorService::SensorEventConnection::needsWakeLock() {
return !mDead && mWakeLockRefCount > 0;
}
+void SensorService::SensorEventConnection::resetWakeLockRefCount() {
+ Mutex::Autolock _l(mConnectionLock);
+ mWakeLockRefCount = 0;
+}
+
void SensorService::SensorEventConnection::dump(String8& result) {
Mutex::Autolock _l(mConnectionLock);
result.appendFormat("\t WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
@@ -1334,11 +1384,14 @@ void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
while (flushInfo.mPendingFlushEventsToSend > 0) {
const int sensor_handle = mSensorInfo.keyAt(i);
flushCompleteEvent.meta_data.sensor = sensor_handle;
- if (mService->getSensorFromHandle(sensor_handle).isWakeUpSensor()) {
+ bool wakeUpSensor = mService->getSensorFromHandle(sensor_handle).isWakeUpSensor();
+ if (wakeUpSensor) {
+ ++mWakeLockRefCount;
flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
}
ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
if (size < 0) {
+ if (wakeUpSensor) --mWakeLockRefCount;
return;
}
ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
@@ -1348,11 +1401,12 @@ void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
}
}
-void SensorService::SensorEventConnection::writeToSocketFromCacheLocked() {
+void SensorService::SensorEventConnection::writeToSocketFromCache() {
// At a time write at most half the size of the receiver buffer in SensorEventQueue OR
// half the size of the socket buffer allocated in BitTube whichever is smaller.
const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
+ Mutex::Autolock _l(mConnectionLock);
// Send pending flush complete events (if any)
sendPendingFlushEventsLocked();
for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
@@ -1503,9 +1557,8 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
}
if (events & ALOOPER_EVENT_OUTPUT) {
- // send sensor data that is stored in mEventCache.
- Mutex::Autolock _l(mConnectionLock);
- writeToSocketFromCacheLocked();
+ // send sensor data that is stored in mEventCache for this connection.
+ mService->sendEventsFromCache(this);
}
return 1;
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 5e3eeb5..8719487 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -101,7 +101,7 @@ class SensorService :
void sendPendingFlushEventsLocked();
// Writes events from mEventCache to the socket.
- void writeToSocketFromCacheLocked();
+ void writeToSocketFromCache();
// Compute the approximate cache size from the FIFO sizes of various sensors registered for
// this connection. Wake up and non-wake up sensors have separate FIFOs but FIFO may be
@@ -182,6 +182,7 @@ class SensorService :
void setFirstFlushPending(int32_t handle, bool value);
void dump(String8& result);
bool needsWakeLock();
+ void resetWakeLockRefCount();
uid_t getUid() const { return mUid; }
};
@@ -230,12 +231,29 @@ class SensorService :
// corresponding applications, if yes the wakelock is released.
void checkWakeLockState();
void checkWakeLockStateLocked();
+ bool isWakeLockAcquired();
bool isWakeUpSensorEvent(const sensors_event_t& event) const;
SensorRecord * getSensorRecord(int handle);
sp<Looper> getLooper() const;
+ // Reset mWakeLockRefCounts for all SensorEventConnections to zero. This may happen if
+ // SensorService did not receive any acknowledgements from apps which have registered for
+ // wake_up sensors.
+ void resetAllWakeLockRefCounts();
+
+ // Acquire or release wake_lock. If wake_lock is acquired, set the timeout in the looper to
+ // 5 seconds and wake the looper.
+ void setWakeLockAcquiredLocked(bool acquire);
+
+ // Send events from the event cache for this particular connection.
+ void sendEventsFromCache(const sp<SensorEventConnection>& connection);
+
+ // Promote all weak referecences in mActiveConnections vector to strong references and add them
+ // to the output vector.
+ void populateActiveConnections(SortedVector< sp<SensorEventConnection> >* activeConnections);
+
// constants
Vector<Sensor> mSensorList;
Vector<Sensor> mUserSensorListDebug;
@@ -247,6 +265,7 @@ class SensorService :
// supported or not.
uint32_t mSocketBufferSize;
sp<Looper> mLooper;
+ sp<SensorEventAckReceiver> mAckReceiver;
// protected by mLock
mutable Mutex mLock;
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index f1ddbe2..3123b63 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -83,6 +83,12 @@ else
LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
endif
+ifneq ($(MAX_VIRTUAL_DISPLAY_DIMENSION),)
+ LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=$(MAX_VIRTUAL_DISPLAY_DIMENSION)
+else
+ LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0
+endif
+
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
LOCAL_CFLAGS += -std=c++11
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 342016e..22d3cec 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -68,7 +68,7 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,
mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
}
-status_t FramebufferSurface::beginFrame(bool /* mustRecompose */) {
+status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
return NO_ERROR;
}
@@ -122,7 +122,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>&
}
// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
-void FramebufferSurface::onFrameAvailable() {
+void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
sp<GraphicBuffer> buf;
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index d0bf22b..8605862 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -56,7 +56,7 @@ public:
private:
virtual ~FramebufferSurface() { }; // this class cannot be overloaded
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const BufferItem& item);
virtual void freeBufferLocked(int slotIndex);
virtual void dumpLocked(String8& result, const char* prefix) const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 91e9a02..c91f0af 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -158,7 +158,7 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
}
}
-void Layer::onFrameAvailable() {
+void Layer::onFrameAvailable(const BufferItem& /* item */) {
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
@@ -277,12 +277,17 @@ static Rect reduce(const Rect& win, const Region& exclude) {
Rect Layer::computeBounds() const {
const Layer::State& s(getDrawingState());
+ return computeBounds(s.activeTransparentRegion);
+}
+
+Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
+ const Layer::State& s(getDrawingState());
Rect win(s.active.w, s.active.h);
if (!s.active.crop.isEmpty()) {
win.intersect(s.active.crop, &win);
}
// subtract the transparent region and snap to the bounds
- return reduce(win, s.activeTransparentRegion);
+ return reduce(win, activeTransparentRegion);
}
FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
@@ -404,7 +409,22 @@ void Layer::setGeometry(
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
- Rect frame(s.transform.transform(computeBounds()));
+ Region activeTransparentRegion(s.activeTransparentRegion);
+ if (!s.active.crop.isEmpty()) {
+ Rect activeCrop(s.active.crop);
+ activeCrop = s.transform.transform(activeCrop);
+ activeCrop.intersect(hw->getViewport(), &activeCrop);
+ activeCrop = s.transform.inverse().transform(activeCrop);
+ // mark regions outside the crop as transparent
+ activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
+ activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
+ s.active.w, s.active.h));
+ activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
+ activeCrop.left, activeCrop.bottom));
+ activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
+ s.active.w, activeCrop.bottom));
+ }
+ Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
frame.intersect(hw->getViewport(), &frame);
const Transform& tr(hw->getTransform());
layer.setFrame(tr.transform(frame));
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2ef39e8..b705bc2 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -142,6 +142,7 @@ public:
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
bool useIdentityTransform) const;
+ Rect computeBounds(const Region& activeTransparentRegion) const;
Rect computeBounds() const;
sp<IBinder> getHandle();
@@ -329,7 +330,7 @@ protected:
private:
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
- virtual void onFrameAvailable();
+ virtual void onFrameAvailable(const BufferItem& item);
virtual void onSidebandStreamChanged();
void commitTransaction();
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index 60edd91..a0cfca9 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -28,7 +28,7 @@ namespace android {
class LayerDim : public Layer
{
-public:
+public:
LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags);
virtual ~LayerDim();
@@ -36,8 +36,7 @@ public:
virtual const char* getTypeId() const { return "LayerDim"; }
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
bool useIdentityTransform) const;
- using Layer::isOpaque;
- virtual bool isOpaque() const { return false; }
+ virtual bool isOpaque(const Layer::State&) const { return false; }
virtual bool isSecure() const { return false; }
virtual bool isFixedSize() const { return true; }
virtual bool isVisible() const;
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 767b714..7cd42e4 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -219,6 +219,10 @@ void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height,
drawMesh(mesh);
}
+void RenderEngine::flush() {
+ glFlush();
+}
+
void RenderEngine::clearWithColor(float red, float green, float blue, float alpha) {
glClearColor(red, green, blue, alpha);
glClear(GL_COLOR_BUFFER_BIT);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index acbff9b..8d7529c 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -67,6 +67,7 @@ public:
virtual void dump(String8& result);
// helpers
+ void flush();
void clearWithColor(float red, float green, float blue, float alpha);
void fillRegionWithColor(const Region& region, uint32_t height,
float red, float green, float blue, float alpha);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e767be2..7d6d7c2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -506,6 +506,9 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
return BAD_VALUE;
}
+ if (!display.get())
+ return NAME_NOT_FOUND;
+
int32_t type = NAME_NOT_FOUND;
for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
if (display == mBuiltinDisplays[i]) {
@@ -652,7 +655,7 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
virtual bool handler() {
Vector<DisplayInfo> configs;
mFlinger.getDisplayConfigs(mDisplay, &configs);
- if(mMode < 0 || static_cast<size_t>(mMode) >= configs.size()) {
+ if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
ALOGE("Attempt to set active config = %d for display with %zu configs",
mMode, configs.size());
}
@@ -1331,7 +1334,22 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
// etc.) but no internal state (i.e. a DisplayDevice).
if (state.surface != NULL) {
- hwcDisplayId = allocateHwcDisplayId(state.type);
+ int width = 0;
+ int status = state.surface->query(
+ NATIVE_WINDOW_WIDTH, &width);
+ ALOGE_IF(status != NO_ERROR,
+ "Unable to query width (%d)", status);
+ int height = 0;
+ status = state.surface->query(
+ NATIVE_WINDOW_HEIGHT, &height);
+ ALOGE_IF(status != NO_ERROR,
+ "Unable to query height (%d)", status);
+ if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
+ (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
+ height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) {
+ hwcDisplayId = allocateHwcDisplayId(state.type);
+ }
+
sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
*mHwc, hwcDisplayId, state.surface,
bqProducer, bqConsumer, state.displayName);
@@ -3205,6 +3223,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
EGLSyncKHR sync;
if (!DEBUG_SCREENSHOTS) {
sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
+ // native fence fd will not be populated until flush() is done.
+ getRenderEngine().flush();
} else {
sync = EGL_NO_SYNC_KHR;
}
@@ -3251,10 +3271,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
} else {
result = BAD_VALUE;
}
+ // queueBuffer takes ownership of syncFd
window->queueBuffer(window, buffer, syncFd);
- if (syncFd != -1) {
- close(syncFd);
- }
}
} else {
result = BAD_VALUE;