summaryrefslogtreecommitdiffstats
path: root/widget/gonk/hwchal
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gonk/hwchal')
-rw-r--r--widget/gonk/hwchal/HwcHAL.cpp214
-rw-r--r--widget/gonk/hwchal/HwcHAL.h70
-rw-r--r--widget/gonk/hwchal/HwcHALBase.h134
3 files changed, 418 insertions, 0 deletions
diff --git a/widget/gonk/hwchal/HwcHAL.cpp b/widget/gonk/hwchal/HwcHAL.cpp
new file mode 100644
index 000000000..1793b75e6
--- /dev/null
+++ b/widget/gonk/hwchal/HwcHAL.cpp
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 et: */
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * 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 "HwcHAL.h"
+#include "libdisplay/GonkDisplay.h"
+#include "mozilla/Assertions.h"
+
+namespace mozilla {
+
+HwcHAL::HwcHAL()
+ : HwcHALBase()
+{
+ // Some HALs don't want to open hwc twice.
+ // If GetDisplay already load hwc module, we don't need to load again
+ mHwc = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
+ if (!mHwc) {
+ printf_stderr("HwcHAL Error: Cannot load hwcomposer");
+ return;
+ }
+}
+
+HwcHAL::~HwcHAL()
+{
+ mHwc = nullptr;
+}
+
+bool
+HwcHAL::Query(QueryType aType)
+{
+ if (!mHwc || !mHwc->query) {
+ return false;
+ }
+
+ bool value = false;
+ int supported = 0;
+ if (mHwc->query(mHwc, static_cast<int>(aType), &supported) == 0/*android::NO_ERROR*/) {
+ value = !!supported;
+ }
+ return value;
+}
+
+int
+HwcHAL::Set(HwcList *aList,
+ uint32_t aDisp)
+{
+ MOZ_ASSERT(mHwc);
+ if (!mHwc) {
+ return -1;
+ }
+
+ HwcList *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr };
+ displays[aDisp] = aList;
+ return mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
+}
+
+int
+HwcHAL::ResetHwc()
+{
+ return Set(nullptr, HWC_DISPLAY_PRIMARY);
+}
+
+int
+HwcHAL::Prepare(HwcList *aList,
+ uint32_t aDisp,
+ hwc_rect_t aDispRect,
+ buffer_handle_t aHandle,
+ int aFenceFd)
+{
+ MOZ_ASSERT(mHwc);
+ if (!mHwc) {
+ printf_stderr("HwcHAL Error: HwcDevice doesn't exist. A fence might be leaked.");
+ return -1;
+ }
+
+ HwcList *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr };
+ displays[aDisp] = aList;
+#if ANDROID_VERSION >= 18
+ aList->outbufAcquireFenceFd = -1;
+ aList->outbuf = nullptr;
+#endif
+ aList->retireFenceFd = -1;
+
+ const auto idx = aList->numHwLayers - 1;
+ aList->hwLayers[idx].hints = 0;
+ aList->hwLayers[idx].flags = 0;
+ aList->hwLayers[idx].transform = 0;
+ aList->hwLayers[idx].handle = aHandle;
+ aList->hwLayers[idx].blending = HWC_BLENDING_PREMULT;
+ aList->hwLayers[idx].compositionType = HWC_FRAMEBUFFER_TARGET;
+ SetCrop(aList->hwLayers[idx], aDispRect);
+ aList->hwLayers[idx].displayFrame = aDispRect;
+ aList->hwLayers[idx].visibleRegionScreen.numRects = 1;
+ aList->hwLayers[idx].visibleRegionScreen.rects = &aList->hwLayers[idx].displayFrame;
+ aList->hwLayers[idx].acquireFenceFd = aFenceFd;
+ aList->hwLayers[idx].releaseFenceFd = -1;
+#if ANDROID_VERSION >= 18
+ aList->hwLayers[idx].planeAlpha = 0xFF;
+#endif
+ return mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
+}
+
+bool
+HwcHAL::SupportTransparency() const
+{
+#if ANDROID_VERSION >= 18
+ return true;
+#endif
+ return false;
+}
+
+uint32_t
+HwcHAL::GetGeometryChangedFlag(bool aGeometryChanged) const
+{
+#if ANDROID_VERSION >= 19
+ return aGeometryChanged ? HWC_GEOMETRY_CHANGED : 0;
+#else
+ return HWC_GEOMETRY_CHANGED;
+#endif
+}
+
+void
+HwcHAL::SetCrop(HwcLayer &aLayer,
+ const hwc_rect_t &aSrcCrop) const
+{
+ if (GetAPIVersion() >= HwcAPIVersion(1, 3)) {
+#if ANDROID_VERSION >= 19
+ aLayer.sourceCropf.left = aSrcCrop.left;
+ aLayer.sourceCropf.top = aSrcCrop.top;
+ 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
+}
+
+uint32_t
+HwcHAL::GetAPIVersion() const
+{
+ if (!mHwc) {
+ // default value: HWC_MODULE_API_VERSION_0_1
+ return 1;
+ }
+ return mHwc->common.version;
+}
+
+// Create HwcHAL
+UniquePtr<HwcHALBase>
+HwcHALBase::CreateHwcHAL()
+{
+ return Move(MakeUnique<HwcHAL>());
+}
+
+} // namespace mozilla
diff --git a/widget/gonk/hwchal/HwcHAL.h b/widget/gonk/hwchal/HwcHAL.h
new file mode 100644
index 000000000..05cb6a45f
--- /dev/null
+++ b/widget/gonk/hwchal/HwcHAL.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 et: */
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * 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 mozilla_HwcHAL
+#define mozilla_HwcHAL
+
+#include "HwcHALBase.h"
+
+namespace mozilla {
+
+class HwcHAL final : public HwcHALBase {
+public:
+ explicit HwcHAL();
+
+ virtual ~HwcHAL();
+
+ virtual bool HasHwc() const override { return static_cast<bool>(mHwc); }
+
+ virtual void SetEGLInfo(hwc_display_t aDpy,
+ hwc_surface_t aSur) override { }
+
+ virtual bool Query(QueryType aType) override;
+
+ virtual int Set(HwcList *aList,
+ uint32_t aDisp) override;
+
+ virtual int ResetHwc() override;
+
+ virtual int Prepare(HwcList *aList,
+ uint32_t aDisp,
+ hwc_rect_t aDispRect,
+ buffer_handle_t aHandle,
+ int aFenceFd) override;
+
+ 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:
+ uint32_t GetAPIVersion() const;
+
+private:
+ HwcDevice *mHwc = nullptr;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_HwcHAL
diff --git a/widget/gonk/hwchal/HwcHALBase.h b/widget/gonk/hwchal/HwcHALBase.h
new file mode 100644
index 000000000..0ef00a325
--- /dev/null
+++ b/widget/gonk/hwchal/HwcHALBase.h
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 et: */
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * 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 mozilla_HwcHALBase
+#define mozilla_HwcHALBase
+
+#include "mozilla/UniquePtr.h"
+#include "nsRect.h"
+
+#include <hardware/hwcomposer.h>
+
+#ifndef HWC_BLIT
+#if ANDROID_VERSION >= 21
+#define HWC_BLIT 0xFF
+#elif ANDROID_VERSION >= 17
+#define HWC_BLIT (HWC_FRAMEBUFFER_TARGET + 1)
+#else
+// ICS didn't support this. However, we define this
+// for passing compilation
+#define HWC_BLIT 0xFF
+#endif // #if ANDROID_VERSION
+#endif // #ifndef HWC_BLIT
+
+namespace mozilla {
+
+#if ANDROID_VERSION >= 17
+using HwcDevice = hwc_composer_device_1_t;
+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 {
+ COLOR_FILL = 0x8,
+ RB_SWAP = 0x40
+ };
+
+public:
+ explicit HwcHALBase() = default;
+
+ virtual ~HwcHALBase() {}
+
+ // Create HwcHAL module, Only HwcComposer2D calls this.
+ // If other modules want to use HwcHAL, please use APIs in
+ // HwcComposer2D
+ static UniquePtr<HwcHALBase> CreateHwcHAL();
+
+ // Check if mHwc exists
+ virtual bool HasHwc() const = 0;
+
+ // Set EGL info (only ICS need this info)
+ virtual void SetEGLInfo(hwc_display_t aEGLDisplay,
+ hwc_surface_t aEGLSurface) = 0;
+
+ // HwcDevice query properties
+ virtual bool Query(QueryType aType) = 0;
+
+ // HwcDevice set
+ virtual int Set(HwcList *aList,
+ uint32_t aDisp) = 0;
+
+ // Reset HwcDevice
+ virtual int ResetHwc() = 0;
+
+ // HwcDevice prepare
+ virtual int Prepare(HwcList *aList,
+ uint32_t aDisp,
+ hwc_rect_t aDispRect,
+ buffer_handle_t aHandle,
+ int aFenceFd) = 0;
+
+ // Check transparency support
+ virtual bool SupportTransparency() const = 0;
+
+ // 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:
+ 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
+
+#endif // mozilla_HwcHALBase