diff options
Diffstat (limited to 'widget/gonk/hwchal')
-rw-r--r-- | widget/gonk/hwchal/HwcHAL.cpp | 214 | ||||
-rw-r--r-- | widget/gonk/hwchal/HwcHAL.h | 70 | ||||
-rw-r--r-- | widget/gonk/hwchal/HwcHALBase.h | 134 |
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 |