gecko-dev/widget/gonk/hwchal/HwcHAL.cpp

215 строки
5.4 KiB
C++

/* -*- 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