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
+