Add DisplaySurface abstraction
DisplayDevice now has a DisplaySurface instead of using
FramebufferSurface directly. FramebufferSurface implements
DisplaySurface, and so does the new VirtualDisplaySurface class.
DisplayDevice now always has a surface, not just for virtual displays.
In this change VirtualDisplaySurface is just a stub; buffers still go
directly from GLES to the final consumer.
Bug: 8384764
Change-Id: I57cb668edbc6c37bfebda90b9222d435bf589f37
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
new file mode 100644
index 0000000..2de6b4c
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_DISPLAY_SURFACE_H
+#define ANDROID_SF_DISPLAY_SURFACE_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class IGraphicBufferProducer;
+class String8;
+
+class DisplaySurface : public virtual RefBase {
+public:
+ virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const = 0;
+
+ // Should be called when composition rendering is complete for a frame (but
+ // eglSwapBuffers hasn't necessarily been called). Required by certain
+ // older drivers for synchronization.
+ // TODO: Remove this when we drop support for HWC 1.0.
+ virtual status_t compositionComplete() = 0;
+
+ // Inform the surface that GLES composition is complete for this frame, and
+ // the surface should make sure that HWComposer has the correct buffer for
+ // this frame. Some implementations may only push a new buffer to
+ // HWComposer if GLES composition took place, others need to push a new
+ // buffer on every frame.
+ virtual status_t advanceFrame() = 0;
+
+ // setReleaseFenceFd stores a fence file descriptor that will signal when
+ // the current buffer is no longer being read. This fence will be returned
+ // to the producer when the current buffer is released by updateTexImage().
+ // Multiple fences can be set for a given buffer; they will be merged into
+ // a single union fence. The GLConsumer will close the file descriptor
+ // when finished with it.
+ virtual status_t setReleaseFenceFd(int fenceFd) = 0;
+
+ virtual void dump(String8& result) const = 0;
+
+protected:
+ DisplaySurface() {}
+ virtual ~DisplaySurface() {}
+};
+
+// ---------------------------------------------------------------------------
+} // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SF_DISPLAY_SURFACE_H
+
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 960f9a9..b5abaac 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -68,6 +68,17 @@
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
}
+sp<IGraphicBufferProducer> FramebufferSurface::getIGraphicBufferProducer() const {
+ return getBufferQueue();
+}
+
+status_t FramebufferSurface::advanceFrame() {
+ // Once we remove FB HAL support, we can call nextBuffer() from here
+ // instead of using onFrameAvailable(). No real benefit, except it'll be
+ // more like VirtualDisplaySurface.
+ return NO_ERROR;
+}
+
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
Mutex::Autolock lock(mMutex);
@@ -147,7 +158,23 @@
return mHwc.fbCompositionComplete();
}
-void FramebufferSurface::dump(String8& result) {
+// Since DisplaySurface and ConsumerBase both have a method with this
+// signature, results will vary based on the static pointer type the caller is
+// using:
+// void dump(FrameBufferSurface* fbs, String8& s) {
+// // calls FramebufferSurface::dump()
+// fbs->dump(s);
+//
+// // calls ConsumerBase::dump() since it is non-virtual
+// static_cast<ConsumerBase*>(fbs)->dump(s);
+//
+// // calls FramebufferSurface::dump() since it is virtual
+// static_cast<DisplaySurface*>(fbs)->dump(s);
+// }
+// To make sure that all of these end up doing the same thing, we just redirect
+// to ConsumerBase::dump() here. It will take the internal lock, and then call
+// virtual dumpLocked(), which is where the real work happens.
+void FramebufferSurface::dump(String8& result) const {
ConsumerBase::dump(result);
}
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 639e720..0aab742 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -22,6 +22,8 @@
#include <gui/ConsumerBase.h>
+#include "DisplaySurface.h"
+
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
@@ -32,23 +34,20 @@
// ---------------------------------------------------------------------------
-class FramebufferSurface : public ConsumerBase {
+class FramebufferSurface : public ConsumerBase,
+ public DisplaySurface {
public:
FramebufferSurface(HWComposer& hwc, int disp);
- status_t compositionComplete();
+ virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
- // TODO(jessehall): This overrides the non-virtual ConsumerBase version.
- // Will rework slightly in a following change.
- void dump(String8& result);
+ virtual status_t compositionComplete();
+ virtual status_t advanceFrame();
+ virtual status_t setReleaseFenceFd(int fenceFd);
- // setReleaseFenceFd stores a fence file descriptor that will signal when the
- // current buffer is no longer being read. This fence will be returned to
- // the producer when the current buffer is released by updateTexImage().
- // Multiple fences can be set for a given buffer; they will be merged into
- // a single union fence. The GLConsumer will close the file descriptor
- // when finished with it.
- status_t setReleaseFenceFd(int fenceFd);
+ // Implementation of DisplaySurface::dump(). Note that ConsumerBase also
+ // has a non-virtual dump() with the same signature.
+ virtual void dump(String8& result) const;
private:
virtual ~FramebufferSurface() { }; // this class cannot be overloaded
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 7df3671..4b6c413 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -617,14 +617,14 @@
}
bool HWComposer::hasHwcComposition(int32_t id) const {
- if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
+ if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
return false;
return mDisplayData[id].hasOvComp;
}
bool HWComposer::hasGlesComposition(int32_t id) const {
- if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
- return false;
+ if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
+ return true;
return mDisplayData[id].hasFbComp;
}
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
new file mode 100644
index 0000000..d30e9bf
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gui/IGraphicBufferProducer.h>
+#include "VirtualDisplaySurface.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int disp,
+ const sp<IGraphicBufferProducer>& sink, const String8& name)
+: mHwc(hwc),
+ mDisplayId(disp),
+ mSink(sink),
+ mName(name)
+{}
+
+VirtualDisplaySurface::~VirtualDisplaySurface() {
+}
+
+sp<IGraphicBufferProducer> VirtualDisplaySurface::getIGraphicBufferProducer() const {
+ return mSink;
+}
+
+status_t VirtualDisplaySurface::compositionComplete() {
+ return NO_ERROR;
+}
+
+status_t VirtualDisplaySurface::advanceFrame() {
+ return NO_ERROR;
+}
+
+status_t VirtualDisplaySurface::setReleaseFenceFd(int fenceFd) {
+ if (fenceFd >= 0) {
+ ALOGW("[%s] unexpected release fence", mName.string());
+ close(fenceFd);
+ }
+ return NO_ERROR;
+}
+
+void VirtualDisplaySurface::dump(String8& result) const {
+}
+
+// ---------------------------------------------------------------------------
+} // namespace android
+// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
new file mode 100644
index 0000000..db886ed
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
+#define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
+
+#include <utils/String8.h>
+#include "DisplaySurface.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class HWComposer;
+
+class VirtualDisplaySurface : public DisplaySurface {
+public:
+ VirtualDisplaySurface(HWComposer& hwc, int disp,
+ const sp<IGraphicBufferProducer>& sink,
+ const String8& name);
+
+ virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
+
+ virtual status_t compositionComplete();
+ virtual status_t advanceFrame();
+ virtual status_t setReleaseFenceFd(int fenceFd);
+ virtual void dump(String8& result) const;
+
+private:
+ virtual ~VirtualDisplaySurface();
+
+ // immutable after construction
+ HWComposer& mHwc;
+ int mDisplayId;
+ sp<IGraphicBufferProducer> mSink;
+ String8 mName;
+};
+
+// ---------------------------------------------------------------------------
+} // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
+