Bug 1144012 - Part 3: Wrap vsync code. r=sotaro
authorBoris Chiou <boris.chiou@gmail.com>
Tue, 23 Jun 2015 15:05:00 +0200
changeset 280851 465f77a0c5179ce24528753ad9e2cc25e2e21f3d
parent 280850 e1b04cf3d129ae384b2cf909e026309ef9931b4b
child 280852 719a075603f4fe98432f98e88ffb9c337fd8e06e
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1144012
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1144012 - Part 3: Wrap vsync code. r=sotaro
widget/gonk/HwcComposer2D.cpp
widget/gonk/HwcComposer2D.h
widget/gonk/hwchal/HwcHAL.cpp
widget/gonk/hwchal/HwcHAL.h
widget/gonk/hwchal/HwcHALBase.h
widget/gonk/hwchal/HwcICS.cpp
widget/gonk/hwchal/HwcICS.h
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -14,38 +14,38 @@
  * 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 <android/log.h>
 #include <string.h>
 
+#include "gfxPrefs.h"
 #include "ImageLayers.h"
 #include "libdisplay/GonkDisplay.h"
 #include "HwcComposer2D.h"
 #include "LayerScope.h"
 #include "Units.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/PLayerTransaction.h"
 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
 #include "mozilla/StaticPtr.h"
+#include "nsThreadUtils.h"
 #include "cutils/properties.h"
 #include "gfx2DGlue.h"
 #include "gfxPlatform.h"
 #include "VsyncSource.h"
 #include "nsScreenManagerGonk.h"
 #include "nsWindow.h"
 
 #if ANDROID_VERSION >= 17
 #include "libdisplay/DisplaySurface.h"
-#include "gfxPrefs.h"
-#include "nsThreadUtils.h"
 #endif
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 #define LOG_TAG "HWComposer"
 
 /*
@@ -66,17 +66,16 @@
 #define LAYER_COUNT_INCREMENTS 5
 
 using namespace android;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 namespace mozilla {
 
-#if ANDROID_VERSION >= 17
 static void
 HookInvalidate(const struct hwc_procs* aProcs)
 {
     HwcComposer2D::GetInstance()->Invalidate();
 }
 
 static void
 HookVsync(const struct hwc_procs* aProcs, int aDisplay,
@@ -87,44 +86,35 @@ HookVsync(const struct hwc_procs* aProcs
 
 static void
 HookHotplug(const struct hwc_procs* aProcs, int aDisplay,
             int aConnected)
 {
     HwcComposer2D::GetInstance()->Hotplug(aDisplay, aConnected);
 }
 
-static const hwc_procs_t sHWCProcs = {
-    &HookInvalidate, // 1st: void (*invalidate)(...)
-    &HookVsync,      // 2nd: void (*vsync)(...)
-    &HookHotplug     // 3rd: void (*hotplug)(...)
-};
-#endif
-
 static StaticRefPtr<HwcComposer2D> sInstance;
 
 HwcComposer2D::HwcComposer2D()
     : mList(nullptr)
     , mMaxLayerCount(0)
     , mColorFill(false)
     , mRBSwapSupport(false)
     , mPrepared(false)
     , mHasHWVsync(false)
     , mLock("mozilla.HwcComposer2D.mLock")
 {
-#if ANDROID_VERSION >= 17
-    RegisterHwcEventCallback();
-#endif
-
     mHal = HwcHALBase::CreateHwcHAL();
     if (!mHal->HasHwc()) {
         LOGD("no hwc support");
         return;
     }
 
+    RegisterHwcEventCallback();
+
     nsIntSize screenSize;
 
     GonkDisplay::NativeData data = GetGonkDisplay()->GetNativeData(GonkDisplay::DISPLAY_PRIMARY);
     ANativeWindow *win = data.mNativeWindow.get();
     win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width);
     win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height);
     mScreenRect = gfx::IntRect(gfx::IntPoint(0, 0), screenSize);
 
@@ -144,56 +134,33 @@ HwcComposer2D::GetInstance()
         sInstance = new HwcComposer2D();
     }
     return sInstance;
 }
 
 bool
 HwcComposer2D::EnableVsync(bool aEnable)
 {
-    // Only support hardware vsync on kitkat, L and up due to inaccurate timings
-    // with JellyBean.
-#if (ANDROID_VERSION == 19 || ANDROID_VERSION >= 21)
     MOZ_ASSERT(NS_IsMainThread());
     if (!mHasHWVsync) {
-      return false;
+        return false;
     }
-
-    HwcDevice* device = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
-    if (!device) {
-      return false;
-    }
-
-    return !device->eventControl(device, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, aEnable) && aEnable;
-#else
-    return false;
-#endif
+    return mHal->EnableVsync(aEnable) && aEnable;
 }
 
-#if ANDROID_VERSION >= 17
 bool
 HwcComposer2D::RegisterHwcEventCallback()
 {
-    HwcDevice* device = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
-    if (!device || !device->registerProcs) {
-        LOGE("Failed to get hwc");
-        return false;
-    }
-
-    // Disable Vsync first, and then register callback functions.
-    device->eventControl(device, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, false);
-    device->registerProcs(device, &sHWCProcs);
-
-    // Only support hardware vsync on kitkat, L and up due to inaccurate timings
-    // with JellyBean.
-#if (ANDROID_VERSION == 19 || ANDROID_VERSION >= 21)
-    mHasHWVsync = gfxPrefs::HardwareVsyncEnabled();
-#else
-    mHasHWVsync = false;
-#endif
+    const HwcHALProcs_t cHWCProcs = {
+        &HookInvalidate,    // 1st: void (*invalidate)(...)
+        &HookVsync,         // 2nd: void (*vsync)(...)
+        &HookHotplug        // 3rd: void (*hotplug)(...)
+    };
+    mHasHWVsync = mHal->RegisterHwcEventCallback(cHWCProcs) &&
+                  gfxPrefs::HardwareVsyncEnabled();
     return mHasHWVsync;
 }
 
 void
 HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp)
 {
     // Only support hardware vsync on kitkat, L and up due to inaccurate timings
     // with JellyBean.
--- a/widget/gonk/HwcComposer2D.h
+++ b/widget/gonk/HwcComposer2D.h
@@ -25,19 +25,17 @@
 #include "Layers.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/layers/FenceUtils.h"      // for FenceHandle
 #include "mozilla/UniquePtr.h"              // for HwcHAL
 
 #include <vector>
 #include <list>
 
-#if ANDROID_VERSION >= 17
 #include <utils/Timers.h>
-#endif
 
 class nsScreenGonk;
 
 namespace mozilla {
 
 namespace gl {
     class GLContext;
 }
@@ -78,22 +76,20 @@ public:
                                   nsIWidget* aWidget,
                                   bool aGeometryChanged) override;
 
     virtual bool Render(nsIWidget* aWidget) override;
 
     virtual bool HasHwc() override { return mHal->HasHwc(); }
 
     bool EnableVsync(bool aEnable);
-#if ANDROID_VERSION >= 17
     bool RegisterHwcEventCallback();
     void Vsync(int aDisplay, int64_t aTimestamp);
     void Invalidate();
     void Hotplug(int aDisplay, int aConnected);
-#endif
     void SetCompositorParent(layers::CompositorParent* aCompositorParent);
 
 private:
     void Reset();
     void Prepare(buffer_handle_t dispHandle, int fence, nsScreenGonk* screen);
     bool Commit(nsScreenGonk* aScreen);
     bool TryHwComposition(nsScreenGonk* aScreen);
     bool ReallocLayerList();
--- a/widget/gonk/hwchal/HwcHAL.cpp
+++ b/widget/gonk/hwchal/HwcHAL.cpp
@@ -145,16 +145,61 @@ HwcHAL::SetCrop(HwcLayer &aLayer,
         aLayer.sourceCropf.right = aSrcCrop.right;
         aLayer.sourceCropf.bottom = aSrcCrop.bottom;
 #endif
     } else {
         aLayer.sourceCrop = aSrcCrop;
     }
 }
 
+bool
+HwcHAL::EnableVsync(bool aEnable)
+{
+    // Only support hardware vsync on kitkat, L and up due to inaccurate timings
+    // with JellyBean.
+#if (ANDROID_VERSION == 19 || ANDROID_VERSION >= 21)
+    if (!mHwc) {
+        return false;
+    }
+    return !mHwc->eventControl(mHwc,
+                               HWC_DISPLAY_PRIMARY,
+                               HWC_EVENT_VSYNC,
+                               aEnable);
+#else
+    return false;
+#endif
+}
+
+bool
+HwcHAL::RegisterHwcEventCallback(const HwcHALProcs_t &aProcs)
+{
+    if (!mHwc || !mHwc->registerProcs) {
+        printf_stderr("Failed to get hwc\n");
+        return false;
+    }
+
+    // Disable Vsync first, and then register callback functions.
+    mHwc->eventControl(mHwc,
+                       HWC_DISPLAY_PRIMARY,
+                       HWC_EVENT_VSYNC,
+                       false);
+    static const hwc_procs_t sHwcJBProcs = {aProcs.invalidate,
+                                            aProcs.vsync,
+                                            aProcs.hotplug};
+    mHwc->registerProcs(mHwc, &sHwcJBProcs);
+
+    // Only support hardware vsync on kitkat, L and up due to inaccurate timings
+    // with JellyBean.
+#if (ANDROID_VERSION == 19 || ANDROID_VERSION >= 21)
+    return true;
+#else
+    return false;
+#endif
+}
+
 void
 HwcHAL::GetHwcAttributes()
 {
     int32_t values[2];
     const uint32_t attrs[] = {
         HWC_DISPLAY_WIDTH,
         HWC_DISPLAY_HEIGHT,
         HWC_DISPLAY_NO_ATTRIBUTE
--- a/widget/gonk/hwchal/HwcHAL.h
+++ b/widget/gonk/hwchal/HwcHAL.h
@@ -50,16 +50,20 @@ public:
 
     virtual bool SupportTransparency() const override;
 
     virtual uint32_t GetGeometryChangedFlag(bool aGeometryChanged) const override;
 
     virtual void SetCrop(HwcLayer &aLayer,
                          const hwc_rect_t &aSrcCrop) const override;
 
+    virtual bool EnableVsync(bool aEnable) override;
+
+    virtual bool RegisterHwcEventCallback(const HwcHALProcs_t &aProcs) override;
+
 private:
     void GetHwcAttributes();
 
     uint32_t GetAPIVersion() const;
 
 private:
     HwcDevice  *mHwc = nullptr;
     hwc_rect_t  mHwcRect = {0};
--- a/widget/gonk/hwchal/HwcHALBase.h
+++ b/widget/gonk/hwchal/HwcHALBase.h
@@ -43,16 +43,28 @@ using HwcDevice = hwc_composer_device_1_
 using HwcList   = hwc_display_contents_1_t;
 using HwcLayer  = hwc_layer_1_t;
 #else
 using HwcDevice = hwc_composer_device_t;
 using HwcList   = hwc_layer_list_t;
 using HwcLayer  = hwc_layer_t;
 #endif
 
+// HwcHAL definition for HwcEvent callback types
+// Note: hwc_procs is different between ICS and later,
+//       and the signature of invalidate is also different.
+//       Use this wrap struct to hide the detail. BTW,
+//       we don't have to register callback functions on ICS, so
+//       there is no callbacks for ICS in HwcHALProcs.
+typedef struct HwcHALProcs {
+    void (*invalidate)(const struct hwc_procs* procs);
+    void (*vsync)(const struct hwc_procs* procs, int disp, int64_t timestamp);
+    void (*hotplug)(const struct hwc_procs* procs, int disp, int connected);
+} HwcHALProcs_t;
+
 // HwcHAL class
 // This class handle all the HAL related work
 // The purpose of HwcHAL is to make HwcComposer2D simpler.
 class HwcHALBase {
 
 public:
     // Query Types. We can add more types easily in the future
     enum class QueryType {
@@ -101,16 +113,22 @@ public:
 
     // Get a geometry change flag
     virtual uint32_t GetGeometryChangedFlag(bool aGeometryChanged) const = 0;
 
     // Set crop help
     virtual void SetCrop(HwcLayer &aLayer,
                          const hwc_rect_t &aSrcCrop) const = 0;
 
+    // Enable HW Vsync
+    virtual bool EnableVsync(bool aEnable) = 0;
+
+    // Register HW event callback functions
+    virtual bool RegisterHwcEventCallback(const HwcHALProcs_t &aProcs) = 0;
+
 protected:
     MOZ_CONSTEXPR static uint32_t HwcAPIVersion(uint32_t aMaj, uint32_t aMin) {
         // HARDWARE_MAKE_API_VERSION_2, from Android hardware.h
         return (((aMaj & 0xff) << 24) | ((aMin & 0xff) << 16) | (1 & 0xffff));
     }
 };
 
 } // namespace mozilla
--- a/widget/gonk/hwchal/HwcICS.cpp
+++ b/widget/gonk/hwchal/HwcICS.cpp
@@ -106,16 +106,28 @@ HwcICS::GetGeometryChangedFlag(bool aGeo
 
 void
 HwcICS::SetCrop(HwcLayer& aLayer,
                 const hwc_rect_t &aSrcCrop) const
 {
     aLayer.sourceCrop = aSrcCrop;
 }
 
+bool
+HwcICS::EnableVsync(bool aEnable)
+{
+    return false;
+}
+
+bool
+HwcICS::RegisterHwcEventCallback(const HwcHALProcs_t &aProcs)
+{
+    return false;
+}
+
 // Create HwcICS
 UniquePtr<HwcHALBase>
 HwcHALBase::CreateHwcHAL()
 {
     return Move(MakeUnique<HwcICS>());
 }
 
 } // namespace mozilla
--- a/widget/gonk/hwchal/HwcICS.h
+++ b/widget/gonk/hwchal/HwcICS.h
@@ -50,16 +50,20 @@ public:
 
     virtual bool SupportTransparency() const override;
 
     virtual uint32_t GetGeometryChangedFlag(bool aGeometryChanged) const override;
 
     virtual void SetCrop(HwcLayer &aLayer,
                          const hwc_rect_t &aSrcCrop) const override;
 
+    virtual bool EnableVsync(bool aEnable) override;
+
+    virtual bool RegisterHwcEventCallback(const HwcHALProcs_t &aProcs) override;
+
 private:
     HwcDevice      *mHwc = nullptr;
     hwc_display_t   mDpy = nullptr;
     hwc_surface_t   mSur = nullptr;
 };
 
 } // namespace mozilla