summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2014-03-13 20:28:16 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-03-13 20:28:17 +0000
commit73ed82f809a40560fd3a6d53d18e5c846362d764 (patch)
treecbf5d50d6c3b7cd49b69c1d95b4f294f64cae8a7 /services
parenta3f519fe6ffb6ac358a3a8015beb94ef1b596ae5 (diff)
parent399184a4cd728ea1421fb0bc1722274a29e38f4a (diff)
downloadframeworks_native-73ed82f809a40560fd3a6d53d18e5c846362d764.zip
frameworks_native-73ed82f809a40560fd3a6d53d18e5c846362d764.tar.gz
frameworks_native-73ed82f809a40560fd3a6d53d18e5c846362d764.tar.bz2
Merge "Add sideband streams to BufferQueue and related classes"
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp11
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h1
-rw-r--r--services/surfaceflinger/Layer.cpp28
-rw-r--r--services/surfaceflinger/Layer.h7
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.cpp27
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.h14
8 files changed, 87 insertions, 9 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 474f633..0ca93c8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -25,6 +25,7 @@
#include <utils/Errors.h>
#include <utils/misc.h>
+#include <utils/NativeHandle.h>
#include <utils/String8.h>
#include <utils/Thread.h>
#include <utils/Trace.h>
@@ -942,12 +943,22 @@ public:
SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
}
+ virtual void setSidebandStream(const sp<NativeHandle>& stream) {
+ ALOG_ASSERT(stream->handle() != NULL);
+ getLayer()->compositionType = HWC_SIDEBAND;
+ getLayer()->sidebandStream = stream->handle();
+ }
virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
if (buffer == 0 || buffer->handle == 0) {
getLayer()->compositionType = HWC_FRAMEBUFFER;
getLayer()->flags |= HWC_SKIP_LAYER;
getLayer()->handle = 0;
} else {
+ if (getLayer()->compositionType == HWC_SIDEBAND) {
+ // If this was a sideband layer but the stream was removed, reset
+ // it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare.
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ }
getLayer()->handle = buffer->handle;
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 9f96113..9218bf6 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -45,9 +45,10 @@ struct framebuffer_device_t;
namespace android {
// ---------------------------------------------------------------------------
-class GraphicBuffer;
class Fence;
class FloatRect;
+class GraphicBuffer;
+class NativeHandle;
class Region;
class String8;
class SurfaceFlinger;
@@ -164,6 +165,7 @@ public:
virtual void setFrame(const Rect& frame) = 0;
virtual void setCrop(const FloatRect& crop) = 0;
virtual void setVisibleRegionScreen(const Region& reg) = 0;
+ virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
virtual void setAcquireFenceFd(int fenceFd) = 0;
virtual void setPlaneAlpha(uint8_t alpha) = 0;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 91be439..11c42e0 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -469,6 +469,10 @@ status_t VirtualDisplaySurface::disconnect(int api) {
return mSource[SOURCE_SINK]->disconnect(api);
}
+status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) {
+ return INVALID_OPERATION;
+}
+
void VirtualDisplaySurface::updateQueueBufferOutput(
const QueueBufferOutput& qbo) {
uint32_t w, h, transformHint, numPendingBuffers;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index cd9a5b0..0d30a1b 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -107,6 +107,7 @@ private:
virtual status_t connect(const sp<IBinder>& token,
int api, bool producerControlledByApp, QueueBufferOutput* output);
virtual status_t disconnect(int api);
+ virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
//
// Utility methods
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 465d376..019d892 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -27,6 +27,7 @@
#include <utils/Errors.h>
#include <utils/Log.h>
+#include <utils/NativeHandle.h>
#include <utils/StopWatch.h>
#include <utils/Trace.h>
@@ -66,6 +67,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
mFormat(PIXEL_FORMAT_NONE),
mTransactionFlags(0),
mQueuedFrames(0),
+ mSidebandStreamChanged(false),
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
@@ -118,7 +120,7 @@ void Layer::onFirstRef() {
mBufferQueue = new SurfaceTextureLayer(mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
- mSurfaceFlingerConsumer->setFrameAvailableListener(this);
+ mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
@@ -158,6 +160,13 @@ void Layer::onFrameAvailable() {
mFlinger->signalLayerUpdate();
}
+void Layer::onSidebandStreamChanged() {
+ if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
+ // mSidebandStreamChanged was false
+ mFlinger->signalLayerUpdate();
+ }
+}
+
// called with SurfaceFlinger::mStateLock from the drawing thread after
// the layer has been remove from the current state list (and just before
// it's removed from the drawing state list)
@@ -413,9 +422,13 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
layer.setVisibleRegionScreen(visible);
- // NOTE: buffer can be NULL if the client never drew into this
- // layer yet, or if we ran out of memory
- layer.setBuffer(mActiveBuffer);
+ if (mSidebandStream.get()) {
+ layer.setSidebandStream(mSidebandStream);
+ } else {
+ // NOTE: buffer can be NULL if the client never drew into this
+ // layer yet, or if we ran out of memory
+ layer.setBuffer(mActiveBuffer);
+ }
}
void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
@@ -907,7 +920,7 @@ bool Layer::setLayerStack(uint32_t layerStack) {
bool Layer::onPreComposition() {
mRefreshPending = false;
- return mQueuedFrames > 0;
+ return mQueuedFrames > 0 || mSidebandStreamChanged;
}
void Layer::onPostComposition() {
@@ -950,6 +963,11 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
ATRACE_CALL();
+ if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
+ // mSidebandStreamChanged was true
+ mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
+ }
+
Region outDirtyRegion;
if (mQueuedFrames > 0) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9283eaa..43de999 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -66,7 +66,7 @@ class SurfaceFlinger;
* This also implements onFrameAvailable(), which notifies SurfaceFlinger
* that new data has arrived.
*/
-class Layer : public SurfaceFlingerConsumer::FrameAvailableListener {
+class Layer : public SurfaceFlingerConsumer::ContentsChangedListener {
static int32_t sSequence;
public:
@@ -313,8 +313,9 @@ protected:
private:
- // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
+ // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
virtual void onFrameAvailable();
+ virtual void onSidebandStreamChanged();
void commitTransaction();
@@ -351,10 +352,12 @@ private:
// thread-safe
volatile int32_t mQueuedFrames;
+ volatile int32_t mSidebandStreamChanged; // used like an atomic boolean
FrameTracker mFrameTracker;
// main thread
sp<GraphicBuffer> mActiveBuffer;
+ sp<NativeHandle> mSidebandStream;
Rect mCurrentCrop;
uint32_t mCurrentTransform;
uint32_t mCurrentScalingMode;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 6dc093e..a412543 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -21,8 +21,9 @@
#include <private/gui/SyncFeatures.h>
-#include <utils/Trace.h>
#include <utils/Errors.h>
+#include <utils/NativeHandle.h>
+#include <utils/Trace.h>
namespace android {
@@ -112,6 +113,10 @@ bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
return mTransformToDisplayInverse;
}
+sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
+ return mConsumer->getSidebandStream();
+}
+
// We need to determine the time when a buffer acquired now will be
// displayed. This can be calculated:
// time when previous buffer's actual-present fence was signaled
@@ -154,6 +159,26 @@ nsecs_t SurfaceFlingerConsumer::computeExpectedPresent()
return prevVsync + hwcLatency * vsyncPeriod + extraPadding;
}
+void SurfaceFlingerConsumer::setContentsChangedListener(
+ const wp<ContentsChangedListener>& listener) {
+ setFrameAvailableListener(listener);
+ Mutex::Autolock lock(mMutex);
+ mContentsChangedListener = listener;
+}
+
+void SurfaceFlingerConsumer::onSidebandStreamChanged() {
+ sp<ContentsChangedListener> listener;
+ { // scope for the lock
+ Mutex::Autolock lock(mMutex);
+ ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get());
+ listener = mContentsChangedListener.promote();
+ }
+
+ if (listener != NULL) {
+ listener->onSidebandStreamChanged();
+ }
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 688ad32..becd5d3 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -27,6 +27,10 @@ namespace android {
*/
class SurfaceFlingerConsumer : public GLConsumer {
public:
+ struct ContentsChangedListener: public FrameAvailableListener {
+ virtual void onSidebandStreamChanged() = 0;
+ };
+
SurfaceFlingerConsumer(const sp<BufferQueue>& bq, uint32_t tex)
: GLConsumer(bq, tex, GLConsumer::TEXTURE_EXTERNAL, false)
{}
@@ -54,9 +58,19 @@ public:
// must be called from SF main thread
bool getTransformToDisplayInverse() const;
+ // Sets the contents changed listener. This should be used instead of
+ // ConsumerBase::setFrameAvailableListener().
+ void setContentsChangedListener(const wp<ContentsChangedListener>& listener);
+
+ sp<NativeHandle> getSidebandStream() const;
+
private:
nsecs_t computeExpectedPresent();
+ virtual void onSidebandStreamChanged();
+
+ wp<ContentsChangedListener> mContentsChangedListener;
+
// Indicates this buffer must be transformed by the inverse transform of the screen
// it is displayed onto. This is applied after GLConsumer::mCurrentTransform.
// This must be set/read from SurfaceFlinger's main thread.