upload android base code part4

This commit is contained in:
August 2018-08-08 17:00:29 +08:00
parent b9e30e05b1
commit 78ea2404cd
23455 changed files with 5250148 additions and 0 deletions

View file

@ -0,0 +1,73 @@
cc_library_static {
name: "libhwcomposer-client",
vendor_available: true,
defaults: ["hidl_defaults"],
export_include_dirs: ["."],
srcs: ["ComposerClient.cpp"],
shared_libs: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.mapper@2.0",
"libbase",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"liblog",
"libsync",
"libutils",
],
}
cc_library_shared {
name: "android.hardware.graphics.composer@2.1-impl",
defaults: ["hidl_defaults"],
proprietary: true,
relative_install_path: "hw",
srcs: ["Hwc.cpp"],
static_libs: ["libhwcomposer-client"],
shared_libs: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.mapper@2.0",
"libbase",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"liblog",
"libsync",
"libutils",
"libhwc2on1adapter"
],
}
cc_binary {
name: "android.hardware.graphics.composer@2.1-service",
defaults: ["hidl_defaults"],
proprietary: true,
relative_install_path: "hw",
srcs: ["service.cpp"],
init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
static_libs: ["libhwcomposer-client"],
shared_libs: [
"android.hardware.graphics.composer@2.1",
"libbase",
"libbinder",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"libhidltransport",
"liblog",
"libsync",
"libutils",
],
}
cc_library_static {
name: "libhwcomposer-command-buffer",
defaults: ["hidl_defaults"],
shared_libs: ["android.hardware.graphics.composer@2.1"],
export_include_dirs: ["."],
}

View file

@ -0,0 +1,130 @@
/*
* Copyright 2017 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_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <hardware/hwcomposer2.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace implementation {
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_0::Transform;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Hdr;
class ComposerBase {
public:
virtual ~ComposerBase() {};
virtual void removeClient() = 0;
virtual void enableCallback(bool enable) = 0;
virtual uint32_t getMaxVirtualDisplayCount() = 0;
virtual Error createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display* outDisplay) = 0;
virtual Error destroyVirtualDisplay(Display display) = 0;
virtual Error createLayer(Display display, Layer* outLayer) = 0;
virtual Error destroyLayer(Display display, Layer layer) = 0;
virtual Error getActiveConfig(Display display, Config* outConfig) = 0;
virtual Error getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) = 0;
virtual Error getColorModes(Display display,
hidl_vec<ColorMode>* outModes) = 0;
virtual Error getDisplayAttribute(Display display, Config config,
IComposerClient::Attribute attribute, int32_t* outValue) = 0;
virtual Error getDisplayConfigs(Display display,
hidl_vec<Config>* outConfigs) = 0;
virtual Error getDisplayName(Display display, hidl_string* outName) = 0;
virtual Error getDisplayType(Display display,
IComposerClient::DisplayType* outType) = 0;
virtual Error getDozeSupport(Display display, bool* outSupport) = 0;
virtual Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
float* outMaxLuminance, float* outMaxAverageLuminance,
float* outMinLuminance) = 0;
virtual Error setActiveConfig(Display display, Config config) = 0;
virtual Error setColorMode(Display display, ColorMode mode) = 0;
virtual Error setPowerMode(Display display,
IComposerClient::PowerMode mode) = 0;
virtual Error setVsyncEnabled(Display display,
IComposerClient::Vsync enabled) = 0;
virtual Error setColorTransform(Display display, const float* matrix,
int32_t hint) = 0;
virtual Error setClientTarget(Display display, buffer_handle_t target,
int32_t acquireFence, int32_t dataspace,
const std::vector<hwc_rect_t>& damage) = 0;
virtual Error setOutputBuffer(Display display, buffer_handle_t buffer,
int32_t releaseFence) = 0;
virtual Error validateDisplay(Display display,
std::vector<Layer>* outChangedLayers,
std::vector<IComposerClient::Composition>* outCompositionTypes,
uint32_t* outDisplayRequestMask,
std::vector<Layer>* outRequestedLayers,
std::vector<uint32_t>* outRequestMasks) = 0;
virtual Error acceptDisplayChanges(Display display) = 0;
virtual Error presentDisplay(Display display, int32_t* outPresentFence,
std::vector<Layer>* outLayers,
std::vector<int32_t>* outReleaseFences) = 0;
virtual Error setLayerCursorPosition(Display display, Layer layer,
int32_t x, int32_t y) = 0;
virtual Error setLayerBuffer(Display display, Layer layer,
buffer_handle_t buffer, int32_t acquireFence) = 0;
virtual Error setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<hwc_rect_t>& damage) = 0;
virtual Error setLayerBlendMode(Display display, Layer layer,
int32_t mode) = 0;
virtual Error setLayerColor(Display display, Layer layer,
IComposerClient::Color color) = 0;
virtual Error setLayerCompositionType(Display display, Layer layer,
int32_t type) = 0;
virtual Error setLayerDataspace(Display display, Layer layer,
int32_t dataspace) = 0;
virtual Error setLayerDisplayFrame(Display display, Layer layer,
const hwc_rect_t& frame) = 0;
virtual Error setLayerPlaneAlpha(Display display, Layer layer,
float alpha) = 0;
virtual Error setLayerSidebandStream(Display display, Layer layer,
buffer_handle_t stream) = 0;
virtual Error setLayerSourceCrop(Display display, Layer layer,
const hwc_frect_t& crop) = 0;
virtual Error setLayerTransform(Display display, Layer layer,
int32_t transform) = 0;
virtual Error setLayerVisibleRegion(Display display, Layer layer,
const std::vector<hwc_rect_t>& visible) = 0;
virtual Error setLayerZOrder(Display display, Layer layer,
uint32_t z) = 0;
};
} // namespace implementation
} // namespace V2_1
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,225 @@
/*
* Copyright 2016 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_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
#include <mutex>
#include <unordered_map>
#include <vector>
#include <hardware/hwcomposer2.h>
#include "IComposerCommandBuffer.h"
#include "ComposerBase.h"
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace implementation {
class BufferCacheEntry {
public:
BufferCacheEntry();
BufferCacheEntry(BufferCacheEntry&& other);
BufferCacheEntry(const BufferCacheEntry& other) = delete;
BufferCacheEntry& operator=(const BufferCacheEntry& other) = delete;
BufferCacheEntry& operator=(buffer_handle_t handle);
~BufferCacheEntry();
buffer_handle_t getHandle() const { return mHandle; }
private:
void clear();
buffer_handle_t mHandle;
};
class ComposerClient : public IComposerClient {
public:
ComposerClient(ComposerBase& hal);
virtual ~ComposerClient();
void initialize();
void onHotplug(Display display, IComposerCallback::Connection connected);
void onRefresh(Display display);
void onVsync(Display display, int64_t timestamp);
// IComposerClient interface
Return<void> registerCallback(
const sp<IComposerCallback>& callback) override;
Return<uint32_t> getMaxVirtualDisplayCount() override;
Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat formatHint, uint32_t outputBufferSlotCount,
createVirtualDisplay_cb hidl_cb) override;
Return<Error> destroyVirtualDisplay(Display display) override;
Return<void> createLayer(Display display, uint32_t bufferSlotCount,
createLayer_cb hidl_cb) override;
Return<Error> destroyLayer(Display display, Layer layer) override;
Return<void> getActiveConfig(Display display,
getActiveConfig_cb hidl_cb) override;
Return<Error> getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override;
Return<void> getColorModes(Display display,
getColorModes_cb hidl_cb) override;
Return<void> getDisplayAttribute(Display display,
Config config, Attribute attribute,
getDisplayAttribute_cb hidl_cb) override;
Return<void> getDisplayConfigs(Display display,
getDisplayConfigs_cb hidl_cb) override;
Return<void> getDisplayName(Display display,
getDisplayName_cb hidl_cb) override;
Return<void> getDisplayType(Display display,
getDisplayType_cb hidl_cb) override;
Return<void> getDozeSupport(Display display,
getDozeSupport_cb hidl_cb) override;
Return<void> getHdrCapabilities(Display display,
getHdrCapabilities_cb hidl_cb) override;
Return<Error> setActiveConfig(Display display, Config config) override;
Return<Error> setColorMode(Display display, ColorMode mode) override;
Return<Error> setPowerMode(Display display, PowerMode mode) override;
Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
Return<Error> setClientTargetSlotCount(Display display,
uint32_t clientTargetSlotCount) override;
Return<Error> setInputCommandQueue(
const MQDescriptorSync<uint32_t>& descriptor) override;
Return<void> getOutputCommandQueue(
getOutputCommandQueue_cb hidl_cb) override;
Return<void> executeCommands(uint32_t inLength,
const hidl_vec<hidl_handle>& inHandles,
executeCommands_cb hidl_cb) override;
protected:
struct LayerBuffers {
std::vector<BufferCacheEntry> Buffers;
// the handle is a sideband stream handle, not a buffer handle
BufferCacheEntry SidebandStream;
};
struct DisplayData {
bool IsVirtual;
std::vector<BufferCacheEntry> ClientTargets;
std::vector<BufferCacheEntry> OutputBuffers;
std::unordered_map<Layer, LayerBuffers> Layers;
DisplayData(bool isVirtual) : IsVirtual(isVirtual) {}
};
class CommandReader : public CommandReaderBase {
public:
CommandReader(ComposerClient& client);
virtual ~CommandReader();
Error parse();
protected:
virtual bool parseCommand(IComposerClient::Command command,
uint16_t length);
bool parseSelectDisplay(uint16_t length);
bool parseSelectLayer(uint16_t length);
bool parseSetColorTransform(uint16_t length);
bool parseSetClientTarget(uint16_t length);
bool parseSetOutputBuffer(uint16_t length);
bool parseValidateDisplay(uint16_t length);
bool parsePresentOrValidateDisplay(uint16_t length);
bool parseAcceptDisplayChanges(uint16_t length);
bool parsePresentDisplay(uint16_t length);
bool parseSetLayerCursorPosition(uint16_t length);
bool parseSetLayerBuffer(uint16_t length);
bool parseSetLayerSurfaceDamage(uint16_t length);
bool parseSetLayerBlendMode(uint16_t length);
bool parseSetLayerColor(uint16_t length);
bool parseSetLayerCompositionType(uint16_t length);
bool parseSetLayerDataspace(uint16_t length);
bool parseSetLayerDisplayFrame(uint16_t length);
bool parseSetLayerPlaneAlpha(uint16_t length);
bool parseSetLayerSidebandStream(uint16_t length);
bool parseSetLayerSourceCrop(uint16_t length);
bool parseSetLayerTransform(uint16_t length);
bool parseSetLayerVisibleRegion(uint16_t length);
bool parseSetLayerZOrder(uint16_t length);
hwc_rect_t readRect();
std::vector<hwc_rect_t> readRegion(size_t count);
hwc_frect_t readFRect();
enum class BufferCache {
CLIENT_TARGETS,
OUTPUT_BUFFERS,
LAYER_BUFFERS,
LAYER_SIDEBAND_STREAMS,
};
Error lookupBufferCacheEntryLocked(BufferCache cache, uint32_t slot,
BufferCacheEntry** outEntry);
Error lookupBuffer(BufferCache cache, uint32_t slot,
bool useCache, buffer_handle_t handle,
buffer_handle_t* outHandle);
Error updateBuffer(BufferCache cache, uint32_t slot,
bool useCache, buffer_handle_t handle);
Error lookupLayerSidebandStream(buffer_handle_t handle,
buffer_handle_t* outHandle)
{
return lookupBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
0, false, handle, outHandle);
}
Error updateLayerSidebandStream(buffer_handle_t handle)
{
return updateBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
0, false, handle);
}
ComposerClient& mClient;
ComposerBase& mHal;
CommandWriterBase& mWriter;
Display mDisplay;
Layer mLayer;
};
virtual std::unique_ptr<CommandReader> createCommandReader();
ComposerBase& mHal;
// 64KiB minus a small space for metadata such as read/write pointers
static constexpr size_t kWriterInitialSize =
64 * 1024 / sizeof(uint32_t) - 16;
std::mutex mCommandMutex;
std::unique_ptr<CommandReader> mReader;
CommandWriterBase mWriter;
sp<IComposerCallback> mCallback;
std::mutex mDisplayDataMutex;
std::unordered_map<Display, DisplayData> mDisplayData;
};
} // namespace implementation
} // namespace V2_1
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H

View file

@ -0,0 +1,773 @@
/*
* Copyright 2016 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.
*/
#define LOG_TAG "HwcPassthrough"
#include "Hwc.h"
#include <chrono>
#include <type_traits>
#include <log/log.h>
#include "ComposerClient.h"
#include "hardware/hwcomposer.h"
#include "hwc2on1adapter/HWC2On1Adapter.h"
using namespace std::chrono_literals;
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace implementation {
HwcHal::HwcHal(const hw_module_t* module)
: mDevice(nullptr), mDispatch(), mAdapter()
{
// Determine what kind of module is available (HWC2 vs HWC1.X).
hw_device_t* device = nullptr;
int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
if (error != 0) {
ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
abort();
}
uint32_t majorVersion = (device->version >> 24) & 0xF;
// If we don't have a HWC2, we need to wrap whatever we have in an adapter.
if (majorVersion != 2) {
uint32_t minorVersion = device->version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
minorVersion = (minorVersion >> 16) & 0xF;
ALOGI("Found HWC implementation v%d.%d", majorVersion, minorVersion);
if (minorVersion < 1) {
ALOGE("Cannot adapt to HWC version %d.%d. Minimum supported is 1.1",
majorVersion, minorVersion);
abort();
}
mAdapter = std::make_unique<HWC2On1Adapter>(
reinterpret_cast<hwc_composer_device_1*>(device));
// Place the adapter in front of the device module.
mDevice = mAdapter.get();
} else {
mDevice = reinterpret_cast<hwc2_device_t*>(device);
}
initCapabilities();
if (majorVersion >= 2 &&
hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
ALOGE("Present fence must be reliable from HWC2 on.");
abort();
}
initDispatch();
}
HwcHal::~HwcHal()
{
hwc2_close(mDevice);
}
void HwcHal::initCapabilities()
{
uint32_t count = 0;
mDevice->getCapabilities(mDevice, &count, nullptr);
std::vector<Capability> caps(count);
mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
std::underlying_type<Capability>::type*>(caps.data()));
caps.resize(count);
mCapabilities.insert(caps.cbegin(), caps.cend());
}
template<typename T>
void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
{
auto pfn = mDevice->getFunction(mDevice, desc);
if (!pfn) {
LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
}
*outPfn = reinterpret_cast<T>(pfn);
}
void HwcHal::initDispatch()
{
initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
&mDispatch.acceptDisplayChanges);
initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer);
initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
&mDispatch.createVirtualDisplay);
initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer);
initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
&mDispatch.destroyVirtualDisplay);
initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump);
initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig);
initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
&mDispatch.getChangedCompositionTypes);
initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
&mDispatch.getClientTargetSupport);
initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes);
initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
&mDispatch.getDisplayAttribute);
initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
&mDispatch.getDisplayConfigs);
initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName);
initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
&mDispatch.getDisplayRequests);
initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType);
initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport);
initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES,
&mDispatch.getHdrCapabilities);
initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
&mDispatch.getMaxVirtualDisplayCount);
initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES,
&mDispatch.getReleaseFences);
initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay);
initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
&mDispatch.registerCallback);
initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig);
initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget);
initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode);
initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM,
&mDispatch.setColorTransform);
initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION,
&mDispatch.setCursorPosition);
initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
&mDispatch.setLayerBlendMode);
initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer);
initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor);
initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
&mDispatch.setLayerCompositionType);
initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE,
&mDispatch.setLayerDataspace);
initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
&mDispatch.setLayerDisplayFrame);
initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
&mDispatch.setLayerPlaneAlpha);
if (hasCapability(Capability::SIDEBAND_STREAM)) {
initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
&mDispatch.setLayerSidebandStream);
}
initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
&mDispatch.setLayerSourceCrop);
initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
&mDispatch.setLayerSurfaceDamage);
initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM,
&mDispatch.setLayerTransform);
initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
&mDispatch.setLayerVisibleRegion);
initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder);
initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer);
initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode);
initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled);
initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay);
initDispatch(HWC2_FUNCTION_SUNXI_SET_DISPLY, &mDispatch.sunxisetdisplay);
}
bool HwcHal::hasCapability(Capability capability) const
{
return (mCapabilities.count(capability) > 0);
}
Return<void> HwcHal::getCapabilities(getCapabilities_cb hidl_cb)
{
std::vector<Capability> caps(
mCapabilities.cbegin(), mCapabilities.cend());
hidl_vec<Capability> caps_reply;
caps_reply.setToExternal(caps.data(), caps.size());
hidl_cb(caps_reply);
return Void();
}
Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
{
uint32_t len = 0;
mDispatch.dump(mDevice, &len, nullptr);
std::vector<char> buf(len + 1);
mDispatch.dump(mDevice, &len, buf.data());
buf.resize(len + 1);
buf[len] = '\0';
hidl_string buf_reply;
buf_reply.setToExternal(buf.data(), len);
hidl_cb(buf_reply);
return Void();
}
Return<void> HwcHal::createClient(createClient_cb hidl_cb)
{
Error err = Error::NONE;
sp<ComposerClient> client;
{
std::unique_lock<std::mutex> lock(mClientMutex);
if (mClient != nullptr) {
// In surface flinger we delete a composer client on one thread and
// then create a new client on another thread. Although surface
// flinger ensures the calls are made in that sequence (destroy and
// then create), sometimes the calls land in the composer service
// inverted (create and then destroy). Wait for a brief period to
// see if the existing client is destroyed.
ALOGI("HwcHal::createClient: Client already exists. Waiting for"
" it to be destroyed.");
mClientDestroyedWait.wait_for(lock, 1s,
[this] { return mClient == nullptr; });
std::string doneMsg = mClient == nullptr ?
"Existing client was destroyed." :
"Existing client was never destroyed!";
ALOGI("HwcHal::createClient: Done waiting. %s", doneMsg.c_str());
}
// only one client is allowed
if (mClient == nullptr) {
client = new ComposerClient(*this);
client->initialize();
mClient = client;
} else {
err = Error::NO_RESOURCES;
}
}
hidl_cb(err, client);
return Void();
}
sp<ComposerClient> HwcHal::getClient()
{
std::lock_guard<std::mutex> lock(mClientMutex);
return (mClient != nullptr) ? mClient.promote() : nullptr;
}
void HwcHal::removeClient()
{
std::lock_guard<std::mutex> lock(mClientMutex);
mClient = nullptr;
mClientDestroyedWait.notify_all();
}
void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int32_t connected)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
auto client = hal->getClient();
if (client != nullptr) {
client->onHotplug(display,
static_cast<IComposerCallback::Connection>(connected));
}
}
void HwcHal::refreshHook(hwc2_callback_data_t callbackData,
hwc2_display_t display)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
auto client = hal->getClient();
if (client != nullptr) {
client->onRefresh(display);
}
}
void HwcHal::vsyncHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int64_t timestamp)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
auto client = hal->getClient();
if (client != nullptr) {
client->onVsync(display, timestamp);
}
}
void HwcHal::enableCallback(bool enable)
{
if (enable) {
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
} else {
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
nullptr);
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
nullptr);
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
nullptr);
}
}
uint32_t HwcHal::getMaxVirtualDisplayCount()
{
return mDispatch.getMaxVirtualDisplayCount(mDevice);
}
Error HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display* outDisplay)
{
int32_t hwc_format = static_cast<int32_t>(*format);
int32_t err = mDispatch.createVirtualDisplay(mDevice, width, height,
&hwc_format, outDisplay);
*format = static_cast<PixelFormat>(hwc_format);
return static_cast<Error>(err);
}
Error HwcHal::destroyVirtualDisplay(Display display)
{
int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display);
return static_cast<Error>(err);
}
Error HwcHal::createLayer(Display display, Layer* outLayer)
{
int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
return static_cast<Error>(err);
}
Error HwcHal::destroyLayer(Display display, Layer layer)
{
int32_t err = mDispatch.destroyLayer(mDevice, display, layer);
return static_cast<Error>(err);
}
Error HwcHal::getActiveConfig(Display display, Config* outConfig)
{
int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig);
return static_cast<Error>(err);
}
Error HwcHal::getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace)
{
int32_t err = mDispatch.getClientTargetSupport(mDevice, display,
width, height, static_cast<int32_t>(format),
static_cast<int32_t>(dataspace));
return static_cast<Error>(err);
}
Error HwcHal::getColorModes(Display display, hidl_vec<ColorMode>* outModes)
{
uint32_t count = 0;
int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
outModes->resize(count);
err = mDispatch.getColorModes(mDevice, display, &count,
reinterpret_cast<std::underlying_type<ColorMode>::type*>(
outModes->data()));
if (err != HWC2_ERROR_NONE) {
*outModes = hidl_vec<ColorMode>();
return static_cast<Error>(err);
}
return Error::NONE;
}
Error HwcHal::getDisplayAttribute(Display display, Config config,
IComposerClient::Attribute attribute, int32_t* outValue)
{
int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config,
static_cast<int32_t>(attribute), outValue);
return static_cast<Error>(err);
}
Error HwcHal::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs)
{
uint32_t count = 0;
int32_t err = mDispatch.getDisplayConfigs(mDevice, display,
&count, nullptr);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
outConfigs->resize(count);
err = mDispatch.getDisplayConfigs(mDevice, display,
&count, outConfigs->data());
if (err != HWC2_ERROR_NONE) {
*outConfigs = hidl_vec<Config>();
return static_cast<Error>(err);
}
return Error::NONE;
}
Error HwcHal::getDisplayName(Display display, hidl_string* outName)
{
uint32_t count = 0;
int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
std::vector<char> buf(count + 1);
err = mDispatch.getDisplayName(mDevice, display, &count, buf.data());
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
buf.resize(count + 1);
buf[count] = '\0';
*outName = buf.data();
return Error::NONE;
}
Error HwcHal::getDisplayType(Display display,
IComposerClient::DisplayType* outType)
{
int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID;
int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type);
*outType = static_cast<IComposerClient::DisplayType>(hwc_type);
return static_cast<Error>(err);
}
Error HwcHal::getDozeSupport(Display display, bool* outSupport)
{
int32_t hwc_support = 0;
int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support);
*outSupport = hwc_support;
return static_cast<Error>(err);
}
Error HwcHal::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
float* outMaxLuminance, float* outMaxAverageLuminance,
float* outMinLuminance)
{
uint32_t count = 0;
int32_t err = mDispatch.getHdrCapabilities(mDevice, display, &count,
nullptr, outMaxLuminance, outMaxAverageLuminance,
outMinLuminance);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
outTypes->resize(count);
err = mDispatch.getHdrCapabilities(mDevice, display, &count,
reinterpret_cast<std::underlying_type<Hdr>::type*>(
outTypes->data()), outMaxLuminance,
outMaxAverageLuminance, outMinLuminance);
if (err != HWC2_ERROR_NONE) {
*outTypes = hidl_vec<Hdr>();
return static_cast<Error>(err);
}
return Error::NONE;
}
Error HwcHal::setActiveConfig(Display display, Config config)
{
int32_t err = mDispatch.setActiveConfig(mDevice, display, config);
return static_cast<Error>(err);
}
Error HwcHal::setColorMode(Display display, ColorMode mode)
{
int32_t err = mDispatch.setColorMode(mDevice, display,
static_cast<int32_t>(mode));
return static_cast<Error>(err);
}
Error HwcHal::setPowerMode(Display display, IComposerClient::PowerMode mode)
{
int32_t err = mDispatch.setPowerMode(mDevice, display,
static_cast<int32_t>(mode));
return static_cast<Error>(err);
}
Error HwcHal::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
{
int32_t err = mDispatch.setVsyncEnabled(mDevice, display,
static_cast<int32_t>(enabled));
return static_cast<Error>(err);
}
Error HwcHal::setColorTransform(Display display, const float* matrix,
int32_t hint)
{
int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint);
return static_cast<Error>(err);
}
Error HwcHal::setClientTarget(Display display, buffer_handle_t target,
int32_t acquireFence, int32_t dataspace,
const std::vector<hwc_rect_t>& damage)
{
hwc_region region = { damage.size(), damage.data() };
int32_t err = mDispatch.setClientTarget(mDevice, display, target,
acquireFence, dataspace, region);
return static_cast<Error>(err);
}
Error HwcHal::setOutputBuffer(Display display, buffer_handle_t buffer,
int32_t releaseFence)
{
int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer,
releaseFence);
// unlike in setClientTarget, releaseFence is owned by us
if (err == HWC2_ERROR_NONE && releaseFence >= 0) {
close(releaseFence);
}
return static_cast<Error>(err);
}
Error HwcHal::validateDisplay(Display display,
std::vector<Layer>* outChangedLayers,
std::vector<IComposerClient::Composition>* outCompositionTypes,
uint32_t* outDisplayRequestMask,
std::vector<Layer>* outRequestedLayers,
std::vector<uint32_t>* outRequestMasks)
{
uint32_t types_count = 0;
uint32_t reqs_count = 0;
int32_t err = mDispatch.validateDisplay(mDevice, display,
&types_count, &reqs_count);
if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
return static_cast<Error>(err);
}
err = mDispatch.getChangedCompositionTypes(mDevice, display,
&types_count, nullptr, nullptr);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
outChangedLayers->resize(types_count);
outCompositionTypes->resize(types_count);
err = mDispatch.getChangedCompositionTypes(mDevice, display,
&types_count, outChangedLayers->data(),
reinterpret_cast<
std::underlying_type<IComposerClient::Composition>::type*>(
outCompositionTypes->data()));
if (err != HWC2_ERROR_NONE) {
outChangedLayers->clear();
outCompositionTypes->clear();
return static_cast<Error>(err);
}
int32_t display_reqs = 0;
err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
&reqs_count, nullptr, nullptr);
if (err != HWC2_ERROR_NONE) {
outChangedLayers->clear();
outCompositionTypes->clear();
return static_cast<Error>(err);
}
outRequestedLayers->resize(reqs_count);
outRequestMasks->resize(reqs_count);
err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
&reqs_count, outRequestedLayers->data(),
reinterpret_cast<int32_t*>(outRequestMasks->data()));
if (err != HWC2_ERROR_NONE) {
outChangedLayers->clear();
outCompositionTypes->clear();
outRequestedLayers->clear();
outRequestMasks->clear();
return static_cast<Error>(err);
}
*outDisplayRequestMask = display_reqs;
return static_cast<Error>(err);
}
Error HwcHal::acceptDisplayChanges(Display display)
{
int32_t err = mDispatch.acceptDisplayChanges(mDevice, display);
return static_cast<Error>(err);
}
Error HwcHal::presentDisplay(Display display, int32_t* outPresentFence,
std::vector<Layer>* outLayers, std::vector<int32_t>* outReleaseFences)
{
*outPresentFence = -1;
int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
uint32_t count = 0;
err = mDispatch.getReleaseFences(mDevice, display, &count,
nullptr, nullptr);
if (err != HWC2_ERROR_NONE) {
ALOGW("failed to get release fences");
return Error::NONE;
}
outLayers->resize(count);
outReleaseFences->resize(count);
err = mDispatch.getReleaseFences(mDevice, display, &count,
outLayers->data(), outReleaseFences->data());
if (err != HWC2_ERROR_NONE) {
ALOGW("failed to get release fences");
outLayers->clear();
outReleaseFences->clear();
return Error::NONE;
}
return static_cast<Error>(err);
}
Error HwcHal::setLayerCursorPosition(Display display, Layer layer,
int32_t x, int32_t y)
{
int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
return static_cast<Error>(err);
}
Error HwcHal::setLayerBuffer(Display display, Layer layer,
buffer_handle_t buffer, int32_t acquireFence)
{
int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer,
buffer, acquireFence);
return static_cast<Error>(err);
}
Error HwcHal::setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<hwc_rect_t>& damage)
{
hwc_region region = { damage.size(), damage.data() };
int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
region);
return static_cast<Error>(err);
}
Error HwcHal::setLayerBlendMode(Display display, Layer layer, int32_t mode)
{
int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode);
return static_cast<Error>(err);
}
Error HwcHal::setLayerColor(Display display, Layer layer,
IComposerClient::Color color)
{
hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
return static_cast<Error>(err);
}
Error HwcHal::setLayerCompositionType(Display display, Layer layer,
int32_t type)
{
int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer,
type);
return static_cast<Error>(err);
}
Error HwcHal::setLayerDataspace(Display display, Layer layer,
int32_t dataspace)
{
int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer,
dataspace);
return static_cast<Error>(err);
}
Error HwcHal::setLayerDisplayFrame(Display display, Layer layer,
const hwc_rect_t& frame)
{
int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
frame);
return static_cast<Error>(err);
}
Error HwcHal::setLayerPlaneAlpha(Display display, Layer layer, float alpha)
{
int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer,
alpha);
return static_cast<Error>(err);
}
Error HwcHal::setLayerSidebandStream(Display display, Layer layer,
buffer_handle_t stream)
{
int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer,
stream);
return static_cast<Error>(err);
}
Error HwcHal::setLayerSourceCrop(Display display, Layer layer,
const hwc_frect_t& crop)
{
int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop);
return static_cast<Error>(err);
}
Error HwcHal::setLayerTransform(Display display, Layer layer,
int32_t transform)
{
int32_t err = mDispatch.setLayerTransform(mDevice, display, layer,
transform);
return static_cast<Error>(err);
}
Error HwcHal::setLayerVisibleRegion(Display display, Layer layer,
const std::vector<hwc_rect_t>& visible)
{
hwc_region_t region = { visible.size(), visible.data() };
int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
region);
return static_cast<Error>(err);
}
Error HwcHal::setLayerZOrder(Display display, Layer layer, uint32_t z)
{
int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z);
return static_cast<Error>(err);
}
Return<Error> HwcHal::setDisplayArg(int32_t disp, int32_t cmd1, int32_t cmd2, int32_t data)
{
int err = 0;
err = mDispatch.sunxisetdisplay(disp, cmd1, cmd2, data);
return static_cast<Error>(err);
}
IComposer* HIDL_FETCH_IComposer(const char*)
{
const hw_module_t* module = nullptr;
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
if (err) {
ALOGE("failed to get hwcomposer module");
return nullptr;
}
return new HwcHal(module);
}
} // namespace implementation
} // namespace V2_1
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,235 @@
/*
* Copyright 2016 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_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
#include <condition_variable>
#include <memory>
#include <mutex>
#include <unordered_set>
#include <vector>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#define HWC2_INCLUDE_STRINGIFICATION
#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
#include "ComposerBase.h"
namespace android {
class HWC2On1Adapter;
}
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace implementation {
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_0::Transform;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Hdr;
class ComposerClient;
class HwcHal : public IComposer, public ComposerBase {
public:
HwcHal(const hw_module_t* module);
virtual ~HwcHal();
bool hasCapability(Capability capability) const;
// IComposer interface
Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
Return<void> createClient(createClient_cb hidl_cb) override;
Return<Error> setDisplayArg(int32_t disp, int32_t cmd1, int32_t cmd2, int32_t data) override;
// ComposerBase interface
void removeClient() override;
void enableCallback(bool enable) override;
uint32_t getMaxVirtualDisplayCount() override;
Error createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display* outDisplay) override;
Error destroyVirtualDisplay(Display display) override;
Error createLayer(Display display, Layer* outLayer) override;
Error destroyLayer(Display display, Layer layer) override;
Error getActiveConfig(Display display, Config* outConfig) override;
Error getClientTargetSupport(Display display,
uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override;
Error getColorModes(Display display,
hidl_vec<ColorMode>* outModes) override;
Error getDisplayAttribute(Display display, Config config,
IComposerClient::Attribute attribute, int32_t* outValue) override;
Error getDisplayConfigs(Display display,
hidl_vec<Config>* outConfigs) override;
Error getDisplayName(Display display, hidl_string* outName) override;
Error getDisplayType(Display display,
IComposerClient::DisplayType* outType) override;
Error getDozeSupport(Display display, bool* outSupport) override;
Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
float* outMaxLuminance, float* outMaxAverageLuminance,
float* outMinLuminance) override;
Error setActiveConfig(Display display, Config config) override;
Error setColorMode(Display display, ColorMode mode) override;
Error setPowerMode(Display display,
IComposerClient::PowerMode mode) override;
Error setVsyncEnabled(Display display,
IComposerClient::Vsync enabled) override;
Error setColorTransform(Display display, const float* matrix,
int32_t hint) override;
Error setClientTarget(Display display, buffer_handle_t target,
int32_t acquireFence, int32_t dataspace,
const std::vector<hwc_rect_t>& damage) override;
Error setOutputBuffer(Display display, buffer_handle_t buffer,
int32_t releaseFence) override;
Error validateDisplay(Display display,
std::vector<Layer>* outChangedLayers,
std::vector<IComposerClient::Composition>* outCompositionTypes,
uint32_t* outDisplayRequestMask,
std::vector<Layer>* outRequestedLayers,
std::vector<uint32_t>* outRequestMasks) override;
Error acceptDisplayChanges(Display display) override;
Error presentDisplay(Display display, int32_t* outPresentFence,
std::vector<Layer>* outLayers,
std::vector<int32_t>* outReleaseFences) override;
Error setLayerCursorPosition(Display display, Layer layer,
int32_t x, int32_t y) override;
Error setLayerBuffer(Display display, Layer layer,
buffer_handle_t buffer, int32_t acquireFence) override;
Error setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<hwc_rect_t>& damage) override;
Error setLayerBlendMode(Display display, Layer layer,
int32_t mode) override;
Error setLayerColor(Display display, Layer layer,
IComposerClient::Color color) override;
Error setLayerCompositionType(Display display, Layer layer,
int32_t type) override;
Error setLayerDataspace(Display display, Layer layer,
int32_t dataspace) override;
Error setLayerDisplayFrame(Display display, Layer layer,
const hwc_rect_t& frame) override;
Error setLayerPlaneAlpha(Display display, Layer layer,
float alpha) override;
Error setLayerSidebandStream(Display display, Layer layer,
buffer_handle_t stream) override;
Error setLayerSourceCrop(Display display, Layer layer,
const hwc_frect_t& crop) override;
Error setLayerTransform(Display display, Layer layer,
int32_t transform) override;
Error setLayerVisibleRegion(Display display, Layer layer,
const std::vector<hwc_rect_t>& visible) override;
Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;
private:
void initCapabilities();
template<typename T>
void initDispatch(hwc2_function_descriptor_t desc, T* outPfn);
void initDispatch();
sp<ComposerClient> getClient();
static void hotplugHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int32_t connected);
static void refreshHook(hwc2_callback_data_t callbackData,
hwc2_display_t display);
static void vsyncHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int64_t timestamp);
hwc2_device_t* mDevice;
std::unordered_set<Capability> mCapabilities;
typedef int (*SUNXI_SET_DISPLY_COMMAND)(int display, int cmd1, int cmd2, int data);
struct {
HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
HWC2_PFN_CREATE_LAYER createLayer;
HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
HWC2_PFN_DESTROY_LAYER destroyLayer;
HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
HWC2_PFN_DUMP dump;
HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
HWC2_PFN_GET_COLOR_MODES getColorModes;
HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
HWC2_PFN_PRESENT_DISPLAY presentDisplay;
HWC2_PFN_REGISTER_CALLBACK registerCallback;
HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
HWC2_PFN_SET_COLOR_MODE setColorMode;
HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
HWC2_PFN_SET_LAYER_COLOR setLayerColor;
HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
HWC2_PFN_SET_POWER_MODE setPowerMode;
HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
SUNXI_SET_DISPLY_COMMAND sunxisetdisplay;
} mDispatch;
std::mutex mClientMutex;
std::condition_variable mClientDestroyedWait;
wp<ComposerClient> mClient;
// If the HWC implementation version is < 2.0, use an adapter to interface
// between HWC 2.0 <-> HWC 1.X.
std::unique_ptr<HWC2On1Adapter> mAdapter;
};
extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
} // namespace implementation
} // namespace V2_1
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H

View file

@ -0,0 +1,881 @@
/*
* Copyright 2016 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_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H
#ifndef LOG_TAG
#warn "IComposerCommandBuffer.h included without LOG_TAG"
#endif
#undef LOG_NDEBUG
#define LOG_NDEBUG 0
#include <algorithm>
#include <limits>
#include <memory>
#include <vector>
#include <inttypes.h>
#include <string.h>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <log/log.h>
#include <sync/sync.h>
#include <fmq/MessageQueue.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::Transform;
using android::hardware::MessageQueue;
using CommandQueueType = MessageQueue<uint32_t, kSynchronizedReadWrite>;
// This class helps build a command queue. Note that all sizes/lengths are in
// units of uint32_t's.
class CommandWriterBase {
public:
CommandWriterBase(uint32_t initialMaxSize)
: mDataMaxSize(initialMaxSize)
{
mData = std::make_unique<uint32_t[]>(mDataMaxSize);
reset();
}
virtual ~CommandWriterBase()
{
reset();
}
void reset()
{
mDataWritten = 0;
mCommandEnd = 0;
// handles in mDataHandles are owned by the caller
mDataHandles.clear();
// handles in mTemporaryHandles are owned by the writer
for (auto handle : mTemporaryHandles) {
native_handle_close(handle);
native_handle_delete(handle);
}
mTemporaryHandles.clear();
}
IComposerClient::Command getCommand(uint32_t offset)
{
uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
return static_cast<IComposerClient::Command>(val &
static_cast<uint32_t>(IComposerClient::Command::OPCODE_MASK));
}
bool writeQueue(bool* outQueueChanged, uint32_t* outCommandLength,
hidl_vec<hidl_handle>* outCommandHandles)
{
// After data are written to the queue, it may not be read by the
// remote reader when
//
// - the writer does not send them (because of other errors)
// - the hwbinder transaction fails
// - the reader does not read them (because of other errors)
//
// Discard the stale data here.
size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
if (staleDataSize > 0) {
ALOGW("discarding stale data from message queue");
CommandQueueType::MemTransaction tx;
if (mQueue->beginRead(staleDataSize, &tx)) {
mQueue->commitRead(staleDataSize);
}
}
// write data to queue, optionally resizing it
if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
if (!mQueue->write(mData.get(), mDataWritten)) {
ALOGE("failed to write commands to message queue");
return false;
}
*outQueueChanged = false;
} else {
auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
if (!newQueue->isValid() ||
!newQueue->write(mData.get(), mDataWritten)) {
ALOGE("failed to prepare a new message queue ");
return false;
}
mQueue = std::move(newQueue);
*outQueueChanged = true;
}
*outCommandLength = mDataWritten;
outCommandHandles->setToExternal(
const_cast<hidl_handle*>(mDataHandles.data()),
mDataHandles.size());
return true;
}
const MQDescriptorSync<uint32_t>* getMQDescriptor() const
{
return (mQueue) ? mQueue->getDesc() : nullptr;
}
static constexpr uint16_t kSelectDisplayLength = 2;
void selectDisplay(Display display)
{
beginCommand(IComposerClient::Command::SELECT_DISPLAY,
kSelectDisplayLength);
write64(display);
endCommand();
}
static constexpr uint16_t kSelectLayerLength = 2;
void selectLayer(Layer layer)
{
beginCommand(IComposerClient::Command::SELECT_LAYER,
kSelectLayerLength);
write64(layer);
endCommand();
}
static constexpr uint16_t kSetErrorLength = 2;
void setError(uint32_t location, Error error)
{
beginCommand(IComposerClient::Command::SET_ERROR, kSetErrorLength);
write(location);
writeSigned(static_cast<int32_t>(error));
endCommand();
}
static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
void setPresentOrValidateResult(uint32_t state) {
beginCommand(IComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, kPresentOrValidateDisplayResultLength);
write(state);
endCommand();
}
void setChangedCompositionTypes(const std::vector<Layer>& layers,
const std::vector<IComposerClient::Composition>& types)
{
size_t totalLayers = std::min(layers.size(), types.size());
size_t currentLayer = 0;
while (currentLayer < totalLayers) {
size_t count = std::min(totalLayers - currentLayer,
static_cast<size_t>(kMaxLength) / 3);
beginCommand(
IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES,
count * 3);
for (size_t i = 0; i < count; i++) {
write64(layers[currentLayer + i]);
writeSigned(static_cast<int32_t>(types[currentLayer + i]));
}
endCommand();
currentLayer += count;
}
}
void setDisplayRequests(uint32_t displayRequestMask,
const std::vector<Layer>& layers,
const std::vector<uint32_t>& layerRequestMasks)
{
size_t totalLayers = std::min(layers.size(),
layerRequestMasks.size());
size_t currentLayer = 0;
while (currentLayer < totalLayers) {
size_t count = std::min(totalLayers - currentLayer,
static_cast<size_t>(kMaxLength - 1) / 3);
beginCommand(IComposerClient::Command::SET_DISPLAY_REQUESTS,
1 + count * 3);
write(displayRequestMask);
for (size_t i = 0; i < count; i++) {
write64(layers[currentLayer + i]);
write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
}
endCommand();
currentLayer += count;
}
}
static constexpr uint16_t kSetPresentFenceLength = 1;
void setPresentFence(int presentFence)
{
beginCommand(IComposerClient::Command::SET_PRESENT_FENCE,
kSetPresentFenceLength);
writeFence(presentFence);
endCommand();
}
void setReleaseFences(const std::vector<Layer>& layers,
const std::vector<int>& releaseFences)
{
size_t totalLayers = std::min(layers.size(), releaseFences.size());
size_t currentLayer = 0;
while (currentLayer < totalLayers) {
size_t count = std::min(totalLayers - currentLayer,
static_cast<size_t>(kMaxLength) / 3);
beginCommand(IComposerClient::Command::SET_RELEASE_FENCES,
count * 3);
for (size_t i = 0; i < count; i++) {
write64(layers[currentLayer + i]);
writeFence(releaseFences[currentLayer + i]);
}
endCommand();
currentLayer += count;
}
}
static constexpr uint16_t kSetColorTransformLength = 17;
void setColorTransform(const float* matrix, ColorTransform hint)
{
beginCommand(IComposerClient::Command::SET_COLOR_TRANSFORM,
kSetColorTransformLength);
for (int i = 0; i < 16; i++) {
writeFloat(matrix[i]);
}
writeSigned(static_cast<int32_t>(hint));
endCommand();
}
void setClientTarget(uint32_t slot, const native_handle_t* target,
int acquireFence, Dataspace dataspace,
const std::vector<IComposerClient::Rect>& damage)
{
bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length);
write(slot);
writeHandle(target, true);
writeFence(acquireFence);
writeSigned(static_cast<int32_t>(dataspace));
// When there are too many rectangles in the damage region and doWrite
// is false, we write no rectangle at all which means the entire
// client target is damaged.
if (doWrite) {
writeRegion(damage);
}
endCommand();
}
static constexpr uint16_t kSetOutputBufferLength = 3;
void setOutputBuffer(uint32_t slot, const native_handle_t* buffer,
int releaseFence)
{
beginCommand(IComposerClient::Command::SET_OUTPUT_BUFFER,
kSetOutputBufferLength);
write(slot);
writeHandle(buffer, true);
writeFence(releaseFence);
endCommand();
}
static constexpr uint16_t kValidateDisplayLength = 0;
void validateDisplay()
{
beginCommand(IComposerClient::Command::VALIDATE_DISPLAY,
kValidateDisplayLength);
endCommand();
}
static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
void presentOrvalidateDisplay()
{
beginCommand(IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
kPresentOrValidateDisplayLength);
endCommand();
}
static constexpr uint16_t kAcceptDisplayChangesLength = 0;
void acceptDisplayChanges()
{
beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES,
kAcceptDisplayChangesLength);
endCommand();
}
static constexpr uint16_t kPresentDisplayLength = 0;
void presentDisplay()
{
beginCommand(IComposerClient::Command::PRESENT_DISPLAY,
kPresentDisplayLength);
endCommand();
}
static constexpr uint16_t kSetLayerCursorPositionLength = 2;
void setLayerCursorPosition(int32_t x, int32_t y)
{
beginCommand(IComposerClient::Command::SET_LAYER_CURSOR_POSITION,
kSetLayerCursorPositionLength);
writeSigned(x);
writeSigned(y);
endCommand();
}
static constexpr uint16_t kSetLayerBufferLength = 3;
void setLayerBuffer(uint32_t slot, const native_handle_t* buffer,
int acquireFence)
{
beginCommand(IComposerClient::Command::SET_LAYER_BUFFER,
kSetLayerBufferLength);
write(slot);
writeHandle(buffer, true);
writeFence(acquireFence);
endCommand();
}
void setLayerSurfaceDamage(
const std::vector<IComposerClient::Rect>& damage)
{
bool doWrite = (damage.size() <= kMaxLength / 4);
size_t length = (doWrite) ? damage.size() * 4 : 0;
beginCommand(IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE,
length);
// When there are too many rectangles in the damage region and doWrite
// is false, we write no rectangle at all which means the entire
// layer is damaged.
if (doWrite) {
writeRegion(damage);
}
endCommand();
}
static constexpr uint16_t kSetLayerBlendModeLength = 1;
void setLayerBlendMode(IComposerClient::BlendMode mode)
{
beginCommand(IComposerClient::Command::SET_LAYER_BLEND_MODE,
kSetLayerBlendModeLength);
writeSigned(static_cast<int32_t>(mode));
endCommand();
}
static constexpr uint16_t kSetLayerColorLength = 1;
void setLayerColor(IComposerClient::Color color)
{
beginCommand(IComposerClient::Command::SET_LAYER_COLOR,
kSetLayerColorLength);
writeColor(color);
endCommand();
}
static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
void setLayerCompositionType(IComposerClient::Composition type)
{
beginCommand(IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE,
kSetLayerCompositionTypeLength);
writeSigned(static_cast<int32_t>(type));
endCommand();
}
static constexpr uint16_t kSetLayerDataspaceLength = 1;
void setLayerDataspace(Dataspace dataspace)
{
beginCommand(IComposerClient::Command::SET_LAYER_DATASPACE,
kSetLayerDataspaceLength);
writeSigned(static_cast<int32_t>(dataspace));
endCommand();
}
static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
void setLayerDisplayFrame(const IComposerClient::Rect& frame)
{
beginCommand(IComposerClient::Command::SET_LAYER_DISPLAY_FRAME,
kSetLayerDisplayFrameLength);
writeRect(frame);
endCommand();
}
static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
void setLayerPlaneAlpha(float alpha)
{
beginCommand(IComposerClient::Command::SET_LAYER_PLANE_ALPHA,
kSetLayerPlaneAlphaLength);
writeFloat(alpha);
endCommand();
}
static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
void setLayerSidebandStream(const native_handle_t* stream)
{
beginCommand(IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM,
kSetLayerSidebandStreamLength);
writeHandle(stream);
endCommand();
}
static constexpr uint16_t kSetLayerSourceCropLength = 4;
void setLayerSourceCrop(const IComposerClient::FRect& crop)
{
beginCommand(IComposerClient::Command::SET_LAYER_SOURCE_CROP,
kSetLayerSourceCropLength);
writeFRect(crop);
endCommand();
}
static constexpr uint16_t kSetLayerTransformLength = 1;
void setLayerTransform(Transform transform)
{
beginCommand(IComposerClient::Command::SET_LAYER_TRANSFORM,
kSetLayerTransformLength);
writeSigned(static_cast<int32_t>(transform));
endCommand();
}
void setLayerVisibleRegion(
const std::vector<IComposerClient::Rect>& visible)
{
bool doWrite = (visible.size() <= kMaxLength / 4);
size_t length = (doWrite) ? visible.size() * 4 : 0;
beginCommand(IComposerClient::Command::SET_LAYER_VISIBLE_REGION,
length);
// When there are too many rectangles in the visible region and
// doWrite is false, we write no rectangle at all which means the
// entire layer is visible.
if (doWrite) {
writeRegion(visible);
}
endCommand();
}
static constexpr uint16_t kSetLayerZOrderLength = 1;
void setLayerZOrder(uint32_t z)
{
beginCommand(IComposerClient::Command::SET_LAYER_Z_ORDER,
kSetLayerZOrderLength);
write(z);
endCommand();
}
protected:
void beginCommand(IComposerClient::Command command, uint16_t length)
{
if (mCommandEnd) {
LOG_FATAL("endCommand was not called before command 0x%x",
command);
}
growData(1 + length);
write(static_cast<uint32_t>(command) | length);
mCommandEnd = mDataWritten + length;
}
void endCommand()
{
if (!mCommandEnd) {
LOG_FATAL("beginCommand was not called");
} else if (mDataWritten > mCommandEnd) {
LOG_FATAL("too much data written");
mDataWritten = mCommandEnd;
} else if (mDataWritten < mCommandEnd) {
LOG_FATAL("too little data written");
while (mDataWritten < mCommandEnd) {
write(0);
}
}
mCommandEnd = 0;
}
void write(uint32_t val)
{
mData[mDataWritten++] = val;
}
void writeSigned(int32_t val)
{
memcpy(&mData[mDataWritten++], &val, sizeof(val));
}
void writeFloat(float val)
{
memcpy(&mData[mDataWritten++], &val, sizeof(val));
}
void write64(uint64_t val)
{
uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
uint32_t hi = static_cast<uint32_t>(val >> 32);
write(lo);
write(hi);
}
void writeRect(const IComposerClient::Rect& rect)
{
writeSigned(rect.left);
writeSigned(rect.top);
writeSigned(rect.right);
writeSigned(rect.bottom);
}
void writeRegion(const std::vector<IComposerClient::Rect>& region)
{
for (const auto& rect : region) {
writeRect(rect);
}
}
void writeFRect(const IComposerClient::FRect& rect)
{
writeFloat(rect.left);
writeFloat(rect.top);
writeFloat(rect.right);
writeFloat(rect.bottom);
}
void writeColor(const IComposerClient::Color& color)
{
write((color.r << 0) |
(color.g << 8) |
(color.b << 16) |
(color.a << 24));
}
// ownership of handle is not transferred
void writeHandle(const native_handle_t* handle, bool useCache)
{
if (!handle) {
writeSigned(static_cast<int32_t>((useCache) ?
IComposerClient::HandleIndex::CACHED :
IComposerClient::HandleIndex::EMPTY));
return;
}
mDataHandles.push_back(handle);
writeSigned(mDataHandles.size() - 1);
}
void writeHandle(const native_handle_t* handle)
{
writeHandle(handle, false);
}
// ownership of fence is transferred
void writeFence(int fence)
{
native_handle_t* handle = nullptr;
if (fence >= 0) {
handle = getTemporaryHandle(1, 0);
if (handle) {
handle->data[0] = fence;
} else {
ALOGW("failed to get temporary handle for fence %d", fence);
sync_wait(fence, -1);
close(fence);
}
}
writeHandle(handle);
}
native_handle_t* getTemporaryHandle(int numFds, int numInts)
{
native_handle_t* handle = native_handle_create(numFds, numInts);
if (handle) {
mTemporaryHandles.push_back(handle);
}
return handle;
}
static constexpr uint16_t kMaxLength =
std::numeric_limits<uint16_t>::max();
private:
void growData(uint32_t grow)
{
uint32_t newWritten = mDataWritten + grow;
if (newWritten < mDataWritten) {
LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32
", growing by %" PRIu32, mDataWritten, grow);
}
if (newWritten <= mDataMaxSize) {
return;
}
uint32_t newMaxSize = mDataMaxSize << 1;
if (newMaxSize < newWritten) {
newMaxSize = newWritten;
}
auto newData = std::make_unique<uint32_t[]>(newMaxSize);
std::copy_n(mData.get(), mDataWritten, newData.get());
mDataMaxSize = newMaxSize;
mData = std::move(newData);
}
uint32_t mDataMaxSize;
std::unique_ptr<uint32_t[]> mData;
uint32_t mDataWritten;
// end offset of the current command
uint32_t mCommandEnd;
std::vector<hidl_handle> mDataHandles;
std::vector<native_handle_t *> mTemporaryHandles;
std::unique_ptr<CommandQueueType> mQueue;
};
// This class helps parse a command queue. Note that all sizes/lengths are in
// units of uint32_t's.
class CommandReaderBase {
public:
CommandReaderBase() : mDataMaxSize(0)
{
reset();
}
bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor)
{
mQueue = std::make_unique<CommandQueueType>(descriptor, false);
if (mQueue->isValid()) {
return true;
} else {
mQueue = nullptr;
return false;
}
}
bool readQueue(uint32_t commandLength,
const hidl_vec<hidl_handle>& commandHandles)
{
if (!mQueue) {
return false;
}
auto quantumCount = mQueue->getQuantumCount();
if (mDataMaxSize < quantumCount) {
mDataMaxSize = quantumCount;
mData = std::make_unique<uint32_t[]>(mDataMaxSize);
}
if (commandLength > mDataMaxSize ||
!mQueue->read(mData.get(), commandLength)) {
ALOGE("failed to read commands from message queue");
return false;
}
mDataSize = commandLength;
mDataRead = 0;
mCommandBegin = 0;
mCommandEnd = 0;
mDataHandles.setToExternal(
const_cast<hidl_handle*>(commandHandles.data()),
commandHandles.size());
return true;
}
void reset()
{
mDataSize = 0;
mDataRead = 0;
mCommandBegin = 0;
mCommandEnd = 0;
mDataHandles.setToExternal(nullptr, 0);
}
protected:
bool isEmpty() const
{
return (mDataRead >= mDataSize);
}
bool beginCommand(IComposerClient::Command* outCommand,
uint16_t* outLength)
{
if (mCommandEnd) {
LOG_FATAL("endCommand was not called for last command");
}
constexpr uint32_t opcode_mask =
static_cast<uint32_t>(IComposerClient::Command::OPCODE_MASK);
constexpr uint32_t length_mask =
static_cast<uint32_t>(IComposerClient::Command::LENGTH_MASK);
uint32_t val = read();
*outCommand = static_cast<IComposerClient::Command>(
val & opcode_mask);
*outLength = static_cast<uint16_t>(val & length_mask);
if (mDataRead + *outLength > mDataSize) {
ALOGE("command 0x%x has invalid command length %" PRIu16,
*outCommand, *outLength);
// undo the read() above
mDataRead--;
return false;
}
mCommandEnd = mDataRead + *outLength;
return true;
}
void endCommand()
{
if (!mCommandEnd) {
LOG_FATAL("beginCommand was not called");
} else if (mDataRead > mCommandEnd) {
LOG_FATAL("too much data read");
mDataRead = mCommandEnd;
} else if (mDataRead < mCommandEnd) {
LOG_FATAL("too little data read");
mDataRead = mCommandEnd;
}
mCommandBegin = mCommandEnd;
mCommandEnd = 0;
}
uint32_t getCommandLoc() const
{
return mCommandBegin;
}
uint32_t read()
{
return mData[mDataRead++];
}
int32_t readSigned()
{
int32_t val;
memcpy(&val, &mData[mDataRead++], sizeof(val));
return val;
}
float readFloat()
{
float val;
memcpy(&val, &mData[mDataRead++], sizeof(val));
return val;
}
uint64_t read64()
{
uint32_t lo = read();
uint32_t hi = read();
return (static_cast<uint64_t>(hi) << 32) | lo;
}
IComposerClient::Color readColor()
{
uint32_t val = read();
return IComposerClient::Color{
static_cast<uint8_t>((val >> 0) & 0xff),
static_cast<uint8_t>((val >> 8) & 0xff),
static_cast<uint8_t>((val >> 16) & 0xff),
static_cast<uint8_t>((val >> 24) & 0xff),
};
}
// ownership of handle is not transferred
const native_handle_t* readHandle(bool* outUseCache)
{
const native_handle_t* handle = nullptr;
int32_t index = readSigned();
switch (index) {
case static_cast<int32_t>(IComposerClient::HandleIndex::EMPTY):
*outUseCache = false;
break;
case static_cast<int32_t>(IComposerClient::HandleIndex::CACHED):
*outUseCache = true;
break;
default:
if (static_cast<size_t>(index) < mDataHandles.size()) {
handle = mDataHandles[index].getNativeHandle();
} else {
ALOGE("invalid handle index %zu", static_cast<size_t>(index));
}
*outUseCache = false;
break;
}
return handle;
}
const native_handle_t* readHandle()
{
bool useCache;
return readHandle(&useCache);
}
// ownership of fence is transferred
int readFence()
{
auto handle = readHandle();
if (!handle || handle->numFds == 0) {
return -1;
}
if (handle->numFds != 1) {
ALOGE("invalid fence handle with %d fds", handle->numFds);
return -1;
}
int fd = dup(handle->data[0]);
if (fd < 0) {
ALOGW("failed to dup fence %d", handle->data[0]);
sync_wait(handle->data[0], -1);
fd = -1;
}
return fd;
}
private:
std::unique_ptr<CommandQueueType> mQueue;
uint32_t mDataMaxSize;
std::unique_ptr<uint32_t[]> mData;
uint32_t mDataSize;
uint32_t mDataRead;
// begin/end offsets of the current command
uint32_t mCommandBegin;
uint32_t mCommandEnd;
hidl_vec<hidl_handle> mDataHandles;
};
} // namespace V2_1
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_COMMAND_BUFFER_H

View file

@ -0,0 +1,6 @@
service hwcomposer-2-1 /vendor/bin/hw/android.hardware.graphics.composer@2.1-service
class hal animation
user system
group graphics drmrpc
capabilities SYS_NICE
onrestart restart surfaceflinger

View file

@ -0,0 +1,44 @@
/*
* Copyright 2016 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.
*/
#define LOG_TAG "android.hardware.graphics.composer@2.1-service"
#include <sched.h>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <binder/ProcessState.h>
#include <hidl/LegacySupport.h>
using android::hardware::graphics::composer::V2_1::IComposer;
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
// the conventional HAL might start binder services
android::ProcessState::initWithDriver("/dev/vndbinder");
android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
android::ProcessState::self()->startThreadPool();
// same as SF main thread
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK,
&param) != 0) {
ALOGE("Couldn't set SCHED_FIFO: %d", errno);
}
return defaultPassthroughServiceImplementation<IComposer>(4);
}