diff options
| author | 2019-02-14 16:01:29 -0800 | |
|---|---|---|
| committer | 2019-03-19 10:25:06 -0700 | |
| commit | e672cd0eef276d65293bb4baa573765534a2431d (patch) | |
| tree | f71ba7ee37587c28308bcc32fa7b96ada5d17e21 | |
| parent | bd8795436dac4d37ff2dea6ae05b126e068c0fa0 (diff) | |
Implement converters for bufferqueue@2.0
Test: make cts -j123 && cts-tradefed run cts-dev -m \
CtsMediaTestCases --compatibility:module-arg \
CtsMediaTestCases:include-annotation:\
android.platform.test.annotations.RequiresDevice
Bug: 112508112
Change-Id: I60f2068788136b01c45e03fc4d846d4e37edc7f2
23 files changed, 1936 insertions, 68 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 8b663bc8ec..4c2e6532ff 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -31,44 +31,7 @@ cc_library_shared { "-Werror", ], cppflags: [ - "-Weverything", - - // The static constructors and destructors in this library have not been noted to - // introduce significant overheads - "-Wno-exit-time-destructors", - "-Wno-global-constructors", - - // We only care about compiling as C++14 - "-Wno-c++98-compat-pedantic", - - // We don't need to enumerate every case in a switch as long as a default case - // is present - "-Wno-switch-enum", - - // Allow calling variadic macros without a __VA_ARGS__ list - "-Wno-gnu-zero-variadic-macro-arguments", - - // Don't warn about struct padding - "-Wno-padded", - - // We are aware of the risks inherent in comparing floats for equality - "-Wno-float-equal", - - // Pure abstract classes trigger this warning - "-Wno-weak-vtables", - - // Allow four-character integer literals - "-Wno-four-char-constants", - - // Allow documentation warnings - "-Wno-documentation", - - // Allow implicit instantiation for templated class function - "-Wno-undefined-func-template", - - // Allow explicitly marking struct as packed even when unnecessary - "-Wno-packed", - + "-Wextra", "-DDEBUG_ONLY_CODE=0", ], @@ -121,30 +84,38 @@ cc_library_shared { "view/Surface.cpp", "bufferqueue/1.0/B2HProducerListener.cpp", "bufferqueue/1.0/H2BGraphicBufferProducer.cpp", + "bufferqueue/1.0/H2BProducerListener.cpp", + "bufferqueue/2.0/B2HGraphicBufferProducer.cpp", + "bufferqueue/2.0/B2HProducerListener.cpp", + "bufferqueue/2.0/H2BGraphicBufferProducer.cpp", + "bufferqueue/2.0/H2BProducerListener.cpp", + "bufferqueue/2.0/types.cpp", ], shared_libs: [ "android.frameworks.bufferhub@1.0", + "android.hardware.graphics.bufferqueue@1.0", + "android.hardware.graphics.bufferqueue@2.0", "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", + "android.hidl.token@1.0-utils", "libbase", - "libsync", "libbinder", - "libhwbinder", "libbufferhub", "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui. - "libpdx_default_transport", "libcutils", "libEGL", "libGLESv2", - "libui", - "libutils", - "libnativewindow", - "liblog", - "libinput", "libhidlbase", "libhidltransport", - "android.hidl.token@1.0-utils", - "android.hardware.graphics.bufferqueue@1.0", + "libhwbinder", + "libinput", + "liblog", + "libnativewindow", + "libpdx_default_transport", + "libsync", + "libui", + "libutils", "libvndksupport", ], @@ -163,16 +134,16 @@ cc_library_shared { "android.frameworks.bufferhub@1.0", "libbufferhub", "libbufferhubqueue", - "libpdx_default_transport", "libinput", + "libpdx_default_transport", ], }, }, header_libs: [ "libdvr_headers", - "libnativebase_headers", "libgui_headers", + "libnativebase_headers", "libpdx_headers", ], @@ -181,9 +152,11 @@ cc_library_shared { "libEGL", "libnativewindow", "libui", - "android.hidl.token@1.0-utils", "android.hardware.graphics.bufferqueue@1.0", + "android.hardware.graphics.bufferqueue@2.0", "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", + "android.hidl.token@1.0-utils", ], export_header_lib_headers: [ diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 8907de4b5d..9dde15dd0e 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -30,16 +30,21 @@ #ifndef NO_BUFFERHUB #include <gui/BufferHubProducer.h> #endif + +#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> #include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferProducer.h> #include <gui/IProducerListener.h> -#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> - namespace android { // ---------------------------------------------------------------------------- -using ::android::hardware::graphics::bufferqueue::V1_0::utils:: +using H2BGraphicBufferProducerV1_0 = + ::android::hardware::graphics::bufferqueue::V1_0::utils:: + H2BGraphicBufferProducer; +using H2BGraphicBufferProducerV2_0 = + ::android::hardware::graphics::bufferqueue::V2_0::utils:: H2BGraphicBufferProducer; enum { @@ -534,7 +539,9 @@ public: BpGraphicBufferProducer::~BpGraphicBufferProducer() {} class HpGraphicBufferProducer : public HpInterface< - BpGraphicBufferProducer, H2BGraphicBufferProducer> { + BpGraphicBufferProducer, + H2BGraphicBufferProducerV1_0, + H2BGraphicBufferProducerV2_0> { public: explicit HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {} diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp index 62abfa81c4..936063a5bd 100644 --- a/libs/gui/IProducerListener.cpp +++ b/libs/gui/IProducerListener.cpp @@ -15,7 +15,8 @@ */ #include <binder/Parcel.h> - +#include <gui/bufferqueue/1.0/H2BProducerListener.h> +#include <gui/bufferqueue/2.0/H2BProducerListener.h> #include <gui/IProducerListener.h> namespace android { @@ -61,7 +62,24 @@ public: // translation unit (see clang warning -Wweak-vtables) BpProducerListener::~BpProducerListener() {} -IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener") +class HpProducerListener : public HpInterface< + BpProducerListener, + hardware::graphics::bufferqueue::V1_0::utils::H2BProducerListener, + hardware::graphics::bufferqueue::V2_0::utils::H2BProducerListener> { +public: + explicit HpProducerListener(const sp<IBinder>& base) : PBase{base} {} + + virtual void onBufferReleased() override { + mBase->onBufferReleased(); + } + + virtual bool needsReleaseNotify() override { + return mBase->needsReleaseNotify(); + } +}; + +IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener, + "android.gui.IProducerListener") status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp b/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp new file mode 100644 index 0000000000..2712f42c89 --- /dev/null +++ b/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2019 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_NDEBUG 0 +#define LOG_TAG "H2BProducerListener@1.0" + +#include <android-base/logging.h> + +#include <gui/bufferqueue/1.0/H2BProducerListener.h> +#include <hidl/Status.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V1_0 { +namespace utils { + +using ::android::hardware::Return; + +H2BProducerListener::H2BProducerListener(sp<HProducerListener> const& base) + : CBase{base} { +} + +void H2BProducerListener::onBufferReleased() { + if (!mBase->onBufferReleased().isOk()) { + LOG(ERROR) << "onBufferReleased: transaction failed."; + } +} + +bool H2BProducerListener::needsReleaseNotify() { + Return<bool> transResult = mBase->needsReleaseNotify(); + if (!transResult.isOk()) { + LOG(ERROR) << "needsReleaseNotify: transaction failed."; + return false; + } + return static_cast<bool>(transResult); +} + +} // namespace utils +} // namespace V1_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp new file mode 100644 index 0000000000..e0395939e9 --- /dev/null +++ b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp @@ -0,0 +1,331 @@ +/* + * Copyright 2019 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_NDEBUG 0 +#define LOG_TAG "H2BGraphicBufferProducer@2.0" + +#include <android-base/logging.h> + +#include <android/hardware/graphics/bufferqueue/2.0/types.h> +#include <android/hardware/graphics/common/1.2/types.h> +#include <gui/bufferqueue/2.0/H2BProducerListener.h> +#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> +#include <ui/Region.h> +#include <vndk/hardware_buffer.h> + +namespace android { + +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// B2HGraphicBufferProducer +// ======================== + +B2HGraphicBufferProducer::B2HGraphicBufferProducer( + sp<BGraphicBufferProducer> const& base) + : mBase{base} { +} + +Return<HStatus> B2HGraphicBufferProducer::setMaxDequeuedBufferCount( + int32_t maxDequeuedBuffers) { + HStatus hStatus{}; + bool converted = b2h( + mBase->setMaxDequeuedBufferCount( + static_cast<int>(maxDequeuedBuffers)), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::requestBuffer( + int32_t slot, + requestBuffer_cb _hidl_cb) { + sp<GraphicBuffer> bBuffer; + HStatus hStatus{}; + HardwareBuffer hBuffer{}; + uint32_t hGenerationNumber{}; + bool converted = + b2h(mBase->requestBuffer( + static_cast<int>(slot), &bBuffer), + &hStatus) && + b2h(bBuffer, &hBuffer, &hGenerationNumber); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + hBuffer, hGenerationNumber); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::setAsyncMode(bool async) { + HStatus hStatus{}; + bool converted = b2h(mBase->setAsyncMode(async), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::dequeueBuffer( + DequeueBufferInput const& input, + dequeueBuffer_cb _hidl_cb) { + int bSlot{}; + sp<BFence> bFence; + HStatus hStatus{}; + DequeueBufferOutput hOutput{}; + HFenceWrapper hFenceWrapper; + bool converted = + b2h(mBase->dequeueBuffer( + &bSlot, + &bFence, + input.width, + input.height, + static_cast<PixelFormat>(input.format), + input.usage, + &hOutput.bufferAge, + nullptr /* outTimestamps */), + &hStatus, + &hOutput.bufferNeedsReallocation, + &hOutput.releaseAllBuffers) && + b2h(bFence, &hFenceWrapper); + hOutput.fence = hFenceWrapper.getHandle(); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + static_cast<int32_t>(bSlot), + hOutput); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::detachBuffer(int32_t slot) { + HStatus hStatus{}; + bool converted = b2h( + mBase->detachBuffer(static_cast<int>(slot)), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::detachNextBuffer( + detachNextBuffer_cb _hidl_cb) { + sp<GraphicBuffer> bBuffer; + sp<BFence> bFence; + HStatus hStatus{}; + HardwareBuffer hBuffer{}; + HFenceWrapper hFenceWrapper; + bool converted = + b2h(mBase->detachNextBuffer(&bBuffer, &bFence), &hStatus) && + b2h(bBuffer, &hBuffer) && + b2h(bFence, &hFenceWrapper); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + hBuffer, + hFenceWrapper.getHandle()); + return {}; +} + +Return<void> B2HGraphicBufferProducer::attachBuffer( + HardwareBuffer const& hBuffer, + uint32_t generationNumber, + attachBuffer_cb _hidl_cb) { + sp<GraphicBuffer> bBuffer; + if (!h2b(hBuffer, &bBuffer) || !bBuffer) { + _hidl_cb(HStatus::UNKNOWN_ERROR, + static_cast<int32_t>(SlotIndex::INVALID), + false); + return {}; + } + bBuffer->setGenerationNumber(generationNumber); + + int bSlot{}; + HStatus hStatus{}; + bool releaseAllBuffers{}; + bool converted = b2h( + mBase->attachBuffer(&bSlot, bBuffer), &hStatus, + nullptr /* bufferNeedsReallocation */, + &releaseAllBuffers); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + static_cast<int32_t>(bSlot), + releaseAllBuffers); + return {}; +} + +Return<void> B2HGraphicBufferProducer::queueBuffer( + int32_t slot, + QueueBufferInput const& hInput, + queueBuffer_cb _hidl_cb) { + using HOutput = QueueBufferOutput; + using BInput = BGraphicBufferProducer::QueueBufferInput; + using BOutput = BGraphicBufferProducer::QueueBufferOutput; + + BInput bInput{ + hInput.timestamp, + hInput.isAutoTimestamp, + static_cast<android_dataspace>(hInput.dataSpace), + {}, /* crop */ + 0 /* scalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE */, + static_cast<uint32_t>(hInput.transform), + {}, /* fence */ + static_cast<uint32_t>(hInput.stickyTransform), + false /* getFrameTimestamps */}; + + // Convert crop. + if (!h2b(hInput.crop, &bInput.crop)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + + // Convert surfaceDamage. + if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + + // Convert fence. + if (!h2b(hInput.fence, &bInput.fence)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + + BOutput bOutput{}; + HStatus hStatus{}; + bool converted = b2h( + mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput), + &hStatus); + + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + HOutput{bOutput.width, + bOutput.height, + static_cast<int32_t>(bOutput.transformHint), + bOutput.numPendingBuffers, + bOutput.nextFrameNumber, + bOutput.bufferReplaced}); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::cancelBuffer( + int32_t slot, + hidl_handle const& fence) { + sp<BFence> bFence; + if (!h2b(fence.getNativeHandle(), &bFence)) { + return {HStatus::UNKNOWN_ERROR}; + } + HStatus hStatus{}; + bool converted = b2h( + mBase->cancelBuffer(static_cast<int>(slot), bFence), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) { + int value{}; + int result = mBase->query(static_cast<int>(what), &value); + _hidl_cb(static_cast<int32_t>(result), static_cast<int32_t>(value)); + return {}; +} + +Return<void> B2HGraphicBufferProducer::connect( + sp<HProducerListener> const& hListener, + HConnectionType hConnectionType, + bool producerControlledByApp, + connect_cb _hidl_cb) { + using BOutput = BGraphicBufferProducer::QueueBufferOutput; + using HOutput = HGraphicBufferProducer::QueueBufferOutput; + sp<BProducerListener> bListener = new H2BProducerListener(hListener); + if (!bListener) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + int bConnectionType; + if (!h2b(hConnectionType, &bConnectionType)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + BOutput bOutput{}; + HStatus hStatus{}; + bool converted = b2h( + mBase->connect(bListener, + bConnectionType, + producerControlledByApp, + &bOutput), + &hStatus); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + HOutput{bOutput.width, + bOutput.height, + static_cast<int32_t>(bOutput.transformHint), + bOutput.numPendingBuffers, + bOutput.nextFrameNumber, + bOutput.bufferReplaced}); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::disconnect( + HConnectionType hConnectionType) { + int bConnectionType; + if (!h2b(hConnectionType, &bConnectionType)) { + return {HStatus::UNKNOWN_ERROR}; + } + HStatus hStatus{}; + bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<HStatus> B2HGraphicBufferProducer::allocateBuffers( + uint32_t width, uint32_t height, + uint32_t format, uint64_t usage) { + mBase->allocateBuffers( + width, height, static_cast<PixelFormat>(format), usage); + return {HStatus::OK}; +} + +Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) { + HStatus hStatus{}; + bool converted = b2h(mBase->allowAllocation(allow), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber( + uint32_t generationNumber) { + HStatus hStatus{}; + bool converted = b2h( + mBase->setGenerationNumber(generationNumber), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout( + int64_t timeoutNs) { + HStatus hStatus{}; + bool converted = b2h( + mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() { + uint64_t outId{}; + HStatus hStatus{}; + bool converted = b2h(mBase->getUniqueId(&outId), &hStatus); + return {converted ? outId : 0}; +} + +Return<void> B2HGraphicBufferProducer::getConsumerName( + getConsumerName_cb _hidl_cb) { + _hidl_cb(hidl_string{mBase->getConsumerName().c_str()}); + return {}; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp b/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp new file mode 100644 index 0000000000..c4c96eba50 --- /dev/null +++ b/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019 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. + */ + +#include <gui/bufferqueue/2.0/B2HProducerListener.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// B2HProducerListener +B2HProducerListener::B2HProducerListener(sp<BProducerListener> const& base) + : mBase{base}, + mNeedsReleaseNotify{base ? base->needsReleaseNotify() : false} { +} + +Return<void> B2HProducerListener::onBuffersReleased(uint32_t count) { + if (mNeedsReleaseNotify) { + for (; count > 0; --count) { + mBase->onBufferReleased(); + } + } + return {}; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp new file mode 100644 index 0000000000..1023ef108a --- /dev/null +++ b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp @@ -0,0 +1,514 @@ +/* + * Copyright 2019 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_NDEBUG 0 +#define LOG_TAG "H2BGraphicBufferProducer@2.0" + +#include <android-base/logging.h> + +#include <android/hardware/graphics/common/1.2/types.h> +#include <gui/bufferqueue/2.0/B2HProducerListener.h> +#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> +#include <ui/Region.h> +#include <vndk/hardware_buffer.h> + +namespace android { + +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// H2BGraphicBufferProducer +// ======================== + +status_t H2BGraphicBufferProducer::requestBuffer(int slot, + sp<GraphicBuffer>* bBuffer) { + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->requestBuffer(slot, + [&converted, &bStatus, bBuffer]( + HStatus hStatus, + HardwareBuffer const& hBuffer, + uint32_t generationNumber) { + converted = + h2b(hStatus, &bStatus) && + h2b(hBuffer, bBuffer); + if (*bBuffer) { + (*bBuffer)->setGenerationNumber(generationNumber); + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "requestBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "requestBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount( + int maxDequeuedBuffers) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setMaxDequeuedBufferCount( + static_cast<int32_t>(maxDequeuedBuffers)); + if (!transResult.isOk()) { + LOG(ERROR) << "setMaxDequeuedBufferCount: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setMaxDequeuedBufferCount: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setAsyncMode(bool async) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setAsyncMode(async); + if (!transResult.isOk()) { + LOG(ERROR) << "setAsyncMode: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setAsyncMode: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::dequeueBuffer( + int* slot, sp<BFence>* fence, + uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, FrameEventHistoryDelta* /* outTimestamps */) { + + using HInput = HGraphicBufferProducer::DequeueBufferInput; + HInput input{w, h, static_cast<uint32_t>(format), usage}; + + using HOutput = HGraphicBufferProducer::DequeueBufferOutput; + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->dequeueBuffer(input, + [&converted, &bStatus, slot, fence, outBufferAge] ( + HStatus hStatus, int32_t hSlot, HOutput const& hOutput) { + converted = h2b(hStatus, &bStatus); + if (!converted || bStatus != OK) { + return; + } + *slot = hSlot; + *outBufferAge = hOutput.bufferAge; + bStatus = + (hOutput.bufferNeedsReallocation ? + BUFFER_NEEDS_REALLOCATION : 0) | + (hOutput.releaseAllBuffers ? + RELEASE_ALL_BUFFERS : 0); + converted = h2b(hOutput.fence, fence); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "dequeueBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "dequeueBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::detachBuffer(int slot) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->detachBuffer( + static_cast<int32_t>(slot)); + if (!transResult.isOk()) { + LOG(ERROR) << "detachBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "detachBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::detachNextBuffer( + sp<GraphicBuffer>* outBuffer, sp<BFence>* outFence) { + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->detachNextBuffer( + [&converted, &bStatus, outBuffer, outFence] ( + HStatus hStatus, + HardwareBuffer const& hBuffer, + hidl_handle const& hFence) { + converted = h2b(hStatus, &bStatus) && + h2b(hBuffer, outBuffer) && + h2b(hFence, outFence); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "detachNextBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "detachNextBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::attachBuffer( + int* outSlot, sp<GraphicBuffer> const& buffer) { + HardwareBuffer hBuffer{}; + uint32_t hGenerationNumber{}; + if (!b2h(buffer, &hBuffer, &hGenerationNumber)) { + LOG(ERROR) << "attachBuffer: invalid input buffer."; + return BAD_VALUE; + } + + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->attachBuffer(hBuffer, hGenerationNumber, + [&converted, &bStatus, outSlot]( + HStatus hStatus, int32_t hSlot, bool releaseAllBuffers) { + converted = h2b(hStatus, &bStatus); + *outSlot = static_cast<int>(hSlot); + if (converted && releaseAllBuffers && bStatus == OK) { + bStatus = IGraphicBufferProducer::RELEASE_ALL_BUFFERS; + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "attachBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "attachBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::queueBuffer( + int slot, + QueueBufferInput const& input, + QueueBufferOutput* output) { + HRect hCrop{}; + (void)b2h(input.crop, &hCrop); + + using HInput = HGraphicBufferProducer::QueueBufferInput; + HInput hInput{ + input.timestamp, + static_cast<bool>(input.isAutoTimestamp), + static_cast<int32_t>(input.dataSpace), + {}, // crop + static_cast<int32_t>(input.transform), + static_cast<int32_t>(input.stickyTransform), + {}, // fence + {} // surfaceDamage + }; + + // Convert crop. + if (!b2h(input.crop, &hInput.crop)) { + LOG(ERROR) << "queueBuffer: corrupted input crop rectangle."; + return UNKNOWN_ERROR; + } + + // Convert surfaceDamage. + size_t numRects; + Rect const* rectArray = input.surfaceDamage.getArray(&numRects); + hInput.surfaceDamage.resize(numRects); + for (size_t i = 0; i < numRects; ++i) { + if (!b2h(rectArray[i], &hInput.surfaceDamage[i])) { + LOG(ERROR) << "queueBuffer: corrupted input surface damage."; + return UNKNOWN_ERROR; + } + } + + // Convert fence. + HFenceWrapper hFenceWrapper; + if (!b2h(input.fence, &hFenceWrapper)) { + LOG(ERROR) << "queueBuffer: corrupted input fence."; + return UNKNOWN_ERROR; + } + hInput.fence = hFenceWrapper.getHandle(); + + using HOutput = HGraphicBufferProducer::QueueBufferOutput; + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->queueBuffer( + static_cast<int32_t>(slot), + hInput, + [&converted, &bStatus, output]( + HStatus hStatus, + HOutput const& hOutput) { + converted = h2b(hStatus, &bStatus); + output->width = hOutput.width; + output->height = hOutput.height; + output->transformHint = + static_cast<uint32_t>(hOutput.transformHint); + output->numPendingBuffers = hOutput.numPendingBuffers; + output->nextFrameNumber = hOutput.nextFrameNumber; + output->bufferReplaced = hOutput.bufferReplaced; + }); + + if (!transResult.isOk()) { + LOG(ERROR) << "queueBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "queueBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::cancelBuffer(int slot, sp<BFence> const& fence) { + HFenceWrapper hFenceWrapper; + if (!b2h(fence, &hFenceWrapper)) { + LOG(ERROR) << "cancelBuffer: corrupted input fence."; + return UNKNOWN_ERROR; + } + status_t bStatus{}; + Return<HStatus> transResult = mBase->cancelBuffer( + static_cast<int32_t>(slot), + hFenceWrapper.getHandle()); + if (!transResult.isOk()) { + LOG(ERROR) << "cancelBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "cancelBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +int H2BGraphicBufferProducer::query(int what, int* value) { + int result{}; + Return<void> transResult = mBase->query( + static_cast<int32_t>(what), + [&result, value](int32_t r, int32_t v) { + result = static_cast<int>(r); + *value = static_cast<int>(v); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "query: transaction failed."; + return FAILED_TRANSACTION; + } + return result; +} + +status_t H2BGraphicBufferProducer::connect( + sp<IProducerListener> const& listener, int api, + bool producerControlledByApp, QueueBufferOutput* output) { + HConnectionType hConnectionType; + if (!b2h(api, &hConnectionType)) { + LOG(ERROR) << "connect: corrupted input connection type."; + return UNKNOWN_ERROR; + } + sp<HProducerListener> hListener = nullptr; + if (listener && listener->needsReleaseNotify()) { + hListener = new B2HProducerListener(listener); + if (!hListener) { + LOG(ERROR) << "connect: failed to wrap listener."; + return UNKNOWN_ERROR; + } + } + + using HOutput = HGraphicBufferProducer::QueueBufferOutput; + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->connect( + hListener, + hConnectionType, + producerControlledByApp, + [&converted, &bStatus, output]( + HStatus hStatus, + HOutput hOutput) { + converted = h2b(hStatus, &bStatus); + output->width = hOutput.width; + output->height = hOutput.height; + output->transformHint = + static_cast<uint32_t>(hOutput.transformHint); + output->numPendingBuffers = hOutput.numPendingBuffers; + output->nextFrameNumber = hOutput.nextFrameNumber; + output->bufferReplaced = hOutput.bufferReplaced; + }); + if (!transResult.isOk()) { + LOG(ERROR) << "connect: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "connect: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; + +} + +status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) { + HConnectionType hConnectionType; + if (mode == DisconnectMode::AllLocal) { + hConnectionType = HConnectionType::CURRENTLY_CONNECTED; + } else if (!b2h(api, &hConnectionType)) { + LOG(ERROR) << "connect: corrupted input connection type."; + return UNKNOWN_ERROR; + } + + status_t bStatus{}; + Return<HStatus> transResult = mBase->disconnect(hConnectionType); + if (!transResult.isOk()) { + LOG(ERROR) << "disconnect: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "disconnect: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setSidebandStream( + sp<NativeHandle> const& stream) { + if (stream) { + LOG(INFO) << "setSidebandStream: not supported."; + return INVALID_OPERATION; + } + return OK; +} + +void H2BGraphicBufferProducer::allocateBuffers( + uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->allocateBuffers( + width, height, static_cast<uint32_t>(format), usage); + if (!transResult.isOk()) { + LOG(ERROR) << "allocateBuffer: transaction failed."; + return; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "allocateBuffer: corrupted transaction."; + return; + } +} + +status_t H2BGraphicBufferProducer::allowAllocation(bool allow) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->allowAllocation(allow); + if (!transResult.isOk()) { + LOG(ERROR) << "allowAllocation: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "allowAllocation: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setGenerationNumber( + uint32_t generationNumber) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setGenerationNumber(generationNumber); + if (!transResult.isOk()) { + LOG(ERROR) << "setGenerationNumber: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setGenerationNumber: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +String8 H2BGraphicBufferProducer::getConsumerName() const { + String8 bName; + Return<void> transResult = mBase->getConsumerName( + [&bName](hidl_string const& name) { + bName = name.c_str(); + }); + return bName; +} + +status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) { + if (sharedBufferMode) { + LOG(INFO) << "setSharedBufferMode: not supported."; + return INVALID_OPERATION; + } + return OK; +} + +status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) { + if (autoRefresh) { + LOG(INFO) << "setAutoRefresh: not supported."; + return INVALID_OPERATION; + } + return OK; +} + +status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setDequeueTimeout( + static_cast<int64_t>(timeout)); + if (!transResult.isOk()) { + LOG(ERROR) << "setDequeueTimeout: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setDequeueTimeout: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::getLastQueuedBuffer( + sp<GraphicBuffer>*, + sp<BFence>*, + float[16]) { + LOG(INFO) << "getLastQueuedBuffer: not supported."; + return INVALID_OPERATION; +} + +void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) { + LOG(INFO) << "getFrameTimestamps: not supported."; +} + +status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const { + Return<uint64_t> transResult = mBase->getUniqueId(); + if (!transResult.isOk()) { + LOG(ERROR) << "getUniqueId: transaction failed."; + return FAILED_TRANSACTION; + } + *outId = static_cast<uint64_t>(transResult); + return OK; +} + +status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t*) const { + LOG(INFO) << "getConsumerUsage: not supported."; + return INVALID_OPERATION; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp b/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp new file mode 100644 index 0000000000..b81a357d63 --- /dev/null +++ b/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2019 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_NDEBUG 0 +#define LOG_TAG "H2BProducerListener@2.0" + +#include <android-base/logging.h> + +#include <gui/bufferqueue/2.0/H2BProducerListener.h> +#include <hidl/Status.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using ::android::hardware::Return; + +H2BProducerListener::H2BProducerListener(sp<HProducerListener> const& base) + : CBase{base} { +} + +void H2BProducerListener::onBufferReleased() { + if (mBase) { + Return<void> transResult = mBase->onBuffersReleased(1); + if (!transResult.isOk()) { + LOG(ERROR) << "onBuffersReleased: transaction failed."; + } + } +} + +bool H2BProducerListener::needsReleaseNotify() { + return static_cast<bool>(mBase); +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/types.cpp b/libs/gui/bufferqueue/2.0/types.cpp new file mode 100644 index 0000000000..a11051739f --- /dev/null +++ b/libs/gui/bufferqueue/2.0/types.cpp @@ -0,0 +1,301 @@ +/* + * Copyright 2019 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. + */ + +#include <cutils/native_handle.h> +#include <gui/BufferQueueCore.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <system/window.h> +#include <vndk/hardware_buffer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// Status +// ====== + +bool b2h(status_t from, HStatus* to, + bool* bufferNeedsReallocation, bool* releaseAllBuffers) { + switch (from) { + case OK: + *to = HStatus::OK; break; + case NO_MEMORY: + *to = HStatus::NO_MEMORY; break; + case NO_INIT: + *to = HStatus::NO_INIT; break; + case BAD_VALUE: + *to = HStatus::BAD_VALUE; break; + case DEAD_OBJECT: + *to = HStatus::DEAD_OBJECT; break; + case INVALID_OPERATION: + *to = HStatus::INVALID_OPERATION; break; + case TIMED_OUT: + *to = HStatus::TIMED_OUT; break; + case WOULD_BLOCK: + *to = HStatus::WOULD_BLOCK; break; + case UNKNOWN_ERROR: + *to = HStatus::UNKNOWN_ERROR; break; + default: + using BGBP = ::android::IGraphicBufferProducer; + status_t mask = + (bufferNeedsReallocation ? BGBP::BUFFER_NEEDS_REALLOCATION : 0) + | (releaseAllBuffers ? BGBP::RELEASE_ALL_BUFFERS : 0); + if (from & ~mask) { + *to = static_cast<HStatus>(from); + } else { + *to = HStatus::OK; + if (bufferNeedsReallocation) { + *bufferNeedsReallocation = from & BGBP::BUFFER_NEEDS_REALLOCATION; + } + if (releaseAllBuffers) { + *releaseAllBuffers = from & BGBP::RELEASE_ALL_BUFFERS; + } + } + } + return true; +} + +bool h2b(HStatus from, status_t* to) { + switch (from) { + case HStatus::OK: + *to = OK; break; + case HStatus::NO_MEMORY: + *to = NO_MEMORY; break; + case HStatus::NO_INIT: + *to = NO_INIT; break; + case HStatus::BAD_VALUE: + *to = BAD_VALUE; break; + case HStatus::DEAD_OBJECT: + *to = DEAD_OBJECT; break; + case HStatus::INVALID_OPERATION: + *to = INVALID_OPERATION; break; + case HStatus::TIMED_OUT: + *to = TIMED_OUT; break; + case HStatus::WOULD_BLOCK: + *to = WOULD_BLOCK; break; + case HStatus::UNKNOWN_ERROR: + *to = UNKNOWN_ERROR; break; + default: + *to = static_cast<status_t>(from); + } + return true; +} + +// Fence +// ===== + +HFenceWrapper::HFenceWrapper(native_handle_t* h) : mHandle{h} { +} + +HFenceWrapper::~HFenceWrapper() { + native_handle_delete(mHandle); +} + +HFenceWrapper& HFenceWrapper::set(native_handle_t* h) { + native_handle_delete(mHandle); + mHandle = h; + return *this; +} + +HFenceWrapper& HFenceWrapper::operator=(native_handle_t* h) { + return set(h); +} + +hidl_handle HFenceWrapper::getHandle() const { + return hidl_handle{mHandle}; +} + +HFenceWrapper::operator hidl_handle() const { + return getHandle(); +} + +bool b2h(sp<BFence> const& from, HFenceWrapper* to) { + if (!from) { + to->set(nullptr); + return true; + } + int fenceFd = from->get(); + if (fenceFd == -1) { + to->set(nullptr); + return true; + } + native_handle_t* nh = native_handle_create(1, 0); + if (!nh) { + return false; + } + nh->data[0] = fenceFd; + to->set(nh); + return true; +} + +bool h2b(native_handle_t const* from, sp<BFence>* to) { + if (!from || from->numFds == 0) { + *to = new ::android::Fence(); + return true; + } + if (from->numFds != 1 || from->numInts != 0) { + return false; + } + *to = new BFence(dup(from->data[0])); + return true; +} + +// ConnectionType +// ============== + +bool b2h(int from, HConnectionType* to) { + *to = static_cast<HConnectionType>(from); + switch (from) { + case BufferQueueCore::CURRENTLY_CONNECTED_API: + *to = HConnectionType::CURRENTLY_CONNECTED; break; + case NATIVE_WINDOW_API_EGL: + *to = HConnectionType::EGL; break; + case NATIVE_WINDOW_API_CPU: + *to = HConnectionType::CPU; break; + case NATIVE_WINDOW_API_MEDIA: + *to = HConnectionType::MEDIA; break; + case NATIVE_WINDOW_API_CAMERA: + *to = HConnectionType::CAMERA; break; + } + return true; +} + +bool h2b(HConnectionType from, int* to) { + *to = static_cast<int>(from); + switch (from) { + case HConnectionType::CURRENTLY_CONNECTED: + *to = BufferQueueCore::CURRENTLY_CONNECTED_API; break; + case HConnectionType::EGL: + *to = NATIVE_WINDOW_API_EGL; break; + case HConnectionType::CPU: + *to = NATIVE_WINDOW_API_CPU; break; + case HConnectionType::MEDIA: + *to = NATIVE_WINDOW_API_MEDIA; break; + case HConnectionType::CAMERA: + *to = NATIVE_WINDOW_API_CAMERA; break; + } + return true; +} + +// Rect +// ==== + +bool b2h(BRect const& from, HRect* to) { + BRect* dst = reinterpret_cast<BRect*>(to->data()); + dst->left = from.left; + dst->top = from.top; + dst->right = from.right; + dst->bottom = from.bottom; + return true; +} + +bool h2b(HRect const& from, BRect* to) { + BRect const* src = reinterpret_cast<BRect const*>(from.data()); + to->left = src->left; + to->top = src->top; + to->right = src->right; + to->bottom = src->bottom; + return true; +} + +// Region +// ====== + +bool b2h(BRegion const& from, HRegion* to) { + size_t numRects; + BRect const* rectArray = from.getArray(&numRects); + to->resize(numRects); + for (size_t i = 0; i < numRects; ++i) { + if (!b2h(rectArray[i], &(*to)[i])) { + return false; + } + } + return true; +} + +bool h2b(HRegion const& from, BRegion* to) { + if (from.size() > 0) { + BRect bRect; + if (!h2b(from[0], &bRect)) { + return false; + } + to->set(bRect); + for (size_t i = 1; i < from.size(); ++i) { + if (!h2b(from[i], &bRect)) { + return false; + } + to->addRectUnchecked( + static_cast<int>(bRect.left), + static_cast<int>(bRect.top), + static_cast<int>(bRect.right), + static_cast<int>(bRect.bottom)); + } + } else { + to->clear(); + } + return true; +} + +// GraphicBuffer +// ============= + +// The handle is not cloned. Its lifetime is tied to the original GraphicBuffer. +bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to, + uint32_t* toGenerationNumber) { + if (!from) { + return false; + } + AHardwareBuffer* hwBuffer = from->toAHardwareBuffer(); + to->nativeHandle.setTo( + const_cast<native_handle_t*>( + AHardwareBuffer_getNativeHandle(hwBuffer)), + false); + AHardwareBuffer_describe( + hwBuffer, + reinterpret_cast<AHardwareBuffer_Desc*>(to->description.data())); + if (toGenerationNumber) { + *toGenerationNumber = from->getGenerationNumber(); + } + return true; +} + +// The handle is cloned. +bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to) { + AHardwareBuffer_Desc const* desc = + reinterpret_cast<AHardwareBuffer_Desc const*>( + from.description.data()); + native_handle_t const* handle = from.nativeHandle; + AHardwareBuffer* hwBuffer; + if (AHardwareBuffer_createFromHandle( + desc, handle, AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, + &hwBuffer) != OK) { + return false; + } + *to = GraphicBuffer::fromAHardwareBuffer(hwBuffer); + return true; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h index 8ff8d81cf6..2f538adebc 100644 --- a/libs/gui/include/gui/IGraphicBufferProducer.h +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -35,6 +35,7 @@ #include <hidl/HybridInterface.h> #include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h> +#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> namespace android { // ---------------------------------------------------------------------------- @@ -42,8 +43,6 @@ namespace android { class IProducerListener; class NativeHandle; class Surface; -typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer - HGraphicBufferProducer; /* * This class defines the Binder IPC interface for the producer side of @@ -62,7 +61,16 @@ typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer class IGraphicBufferProducer : public IInterface { public: - DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, HGraphicBufferProducer) + using HGraphicBufferProducerV1_0 = + ::android::hardware::graphics::bufferqueue::V1_0:: + IGraphicBufferProducer; + using HGraphicBufferProducerV2_0 = + ::android::hardware::graphics::bufferqueue::V2_0:: + IGraphicBufferProducer; + + DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, + HGraphicBufferProducerV1_0, + HGraphicBufferProducerV2_0) enum { // A flag returned by dequeueBuffer when the client needs to call @@ -366,7 +374,6 @@ public: const HdrMetadata& getHdrMetadata() const { return hdrMetadata; } void setHdrMetadata(const HdrMetadata& metadata) { hdrMetadata = metadata; } - private: int64_t timestamp{0}; int isAutoTimestamp{0}; android_dataspace dataSpace{HAL_DATASPACE_UNKNOWN}; diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h index e808bd3bc3..a13d8e4945 100644 --- a/libs/gui/include/gui/IProducerListener.h +++ b/libs/gui/include/gui/IProducerListener.h @@ -17,8 +17,10 @@ #ifndef ANDROID_GUI_IPRODUCERLISTENER_H #define ANDROID_GUI_IPRODUCERLISTENER_H +#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h> +#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h> #include <binder/IInterface.h> - +#include <hidl/HybridInterface.h> #include <utils/RefBase.h> namespace android { @@ -47,7 +49,14 @@ public: class IProducerListener : public ProducerListener, public IInterface { public: - DECLARE_META_INTERFACE(ProducerListener) + using HProducerListener1 = + ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener; + using HProducerListener2 = + ::android::hardware::graphics::bufferqueue::V2_0::IProducerListener; + DECLARE_HYBRID_META_INTERFACE( + ProducerListener, + HProducerListener1, + HProducerListener2) }; class BnProducerListener : public BnInterface<IProducerListener> diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h new file mode 100644 index 0000000000..211fdd5351 --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h @@ -0,0 +1,52 @@ +/* + * Copyright 2019 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_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H + +#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h> +#include <gui/IProducerListener.h> +#include <hidl/HybridInterface.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V1_0 { +namespace utils { + +using HProducerListener = ::android::hardware::graphics::bufferqueue::V1_0:: + IProducerListener; + +using BProducerListener = ::android::IProducerListener; + +class H2BProducerListener + : public H2BConverter<HProducerListener, BnProducerListener> { +public: + H2BProducerListener(sp<HProducerListener> const& base); + virtual void onBufferReleased() override; + virtual bool needsReleaseNotify() override; +}; + +} // namespace utils +} // namespace V1_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h new file mode 100644 index 0000000000..1c58167752 --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h @@ -0,0 +1,121 @@ +/* + * Copyright 2019 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_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H + +#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <hidl/HidlSupport.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using HGraphicBufferProducer = + ::android::hardware::graphics::bufferqueue::V2_0:: + IGraphicBufferProducer; +using BGraphicBufferProducer = + ::android:: + IGraphicBufferProducer; +using HProducerListener = + ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; + +using ::android::hardware::Return; +using ::android::hardware::hidl_handle; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; + +using ::android::hardware::graphics::common::V1_2::HardwareBuffer; + +class B2HGraphicBufferProducer : public HGraphicBufferProducer { +public: + B2HGraphicBufferProducer(sp<BGraphicBufferProducer> const& base); + + virtual Return<HStatus> setMaxDequeuedBufferCount( + int32_t maxDequeuedBuffers) override; + + virtual Return<void> requestBuffer( + int32_t slot, + requestBuffer_cb _hidl_cb) override; + + virtual Return<HStatus> setAsyncMode(bool async) override; + + virtual Return<void> dequeueBuffer( + DequeueBufferInput const& input, + dequeueBuffer_cb _hidl_cb) override; + + virtual Return<HStatus> detachBuffer(int32_t slot) override; + + virtual Return<void> detachNextBuffer( + detachNextBuffer_cb _hidl_cb) override; + + virtual Return<void> attachBuffer( + HardwareBuffer const& buffer, + uint32_t generationNumber, + attachBuffer_cb _hidl_cb) override; + + virtual Return<void> queueBuffer( + int32_t slot, + QueueBufferInput const& input, + queueBuffer_cb _hidl_cb) override; + + virtual Return<HStatus> cancelBuffer( + int32_t slot, + hidl_handle const& fence) override; + + virtual Return<void> query(int32_t what, query_cb _hidl_cb) override; + + virtual Return<void> connect( + sp<HProducerListener> const& listener, + HConnectionType api, + bool producerControlledByApp, + connect_cb _hidl_cb) override; + + virtual Return<HStatus> disconnect(HConnectionType api) override; + + virtual Return<HStatus> allocateBuffers( + uint32_t width, uint32_t height, + uint32_t format, uint64_t usage) override; + + virtual Return<HStatus> allowAllocation(bool allow) override; + + virtual Return<HStatus> setGenerationNumber(uint32_t generationNumber) override; + + virtual Return<HStatus> setDequeueTimeout(int64_t timeoutNs) override; + + virtual Return<uint64_t> getUniqueId() override; + + virtual Return<void> getConsumerName(getConsumerName_cb _hidl_cb) override; + +protected: + sp<BGraphicBufferProducer> mBase; +}; + + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H diff --git a/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h new file mode 100644 index 0000000000..b48a4736ad --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h @@ -0,0 +1,57 @@ +/* + * Copyright 2019 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_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H + +#include <android/hidl/base/1.0/IBase.h> +#include <binder/IBinder.h> +#include <gui/IProducerListener.h> +#include <hidl/Status.h> + +#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using ::android::hardware::Return; + +using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; + +using BProducerListener = ::android::IProducerListener; + +struct B2HProducerListener : public HProducerListener { + explicit B2HProducerListener(sp<BProducerListener> const& base); + Return<void> onBuffersReleased(uint32_t count) override; +protected: + sp<BProducerListener> mBase; + bool mNeedsReleaseNotify; +}; + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h new file mode 100644 index 0000000000..7dd16172cf --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h @@ -0,0 +1,107 @@ +/* + * Copyright 2019 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_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H + +#include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> +#include <hidl/HybridInterface.h> +#include <ui/Fence.h> + +#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using ::android::BnGraphicBufferProducer; +using ::android::IProducerListener; +using Fence = ::android::Fence; + +using HGraphicBufferProducer = + ::android::hardware::graphics::bufferqueue::V2_0:: + IGraphicBufferProducer; +using HProducerListener = + ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; +using BGraphicBufferProducer = + ::android::IGraphicBufferProducer; + +struct H2BGraphicBufferProducer + : public ::android::H2BConverter<HGraphicBufferProducer, + BnGraphicBufferProducer> { + explicit H2BGraphicBufferProducer( + sp<HGraphicBufferProducer> const& base) : CBase(base) {} + + virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override; + virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override; + virtual status_t setAsyncMode(bool async) override; + virtual status_t dequeueBuffer( + int* slot, sp<Fence>* fence, + uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) override; + virtual status_t detachBuffer(int slot) override; + virtual status_t detachNextBuffer( + sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence) override; + virtual status_t attachBuffer( + int* outSlot, + sp<GraphicBuffer> const& buffer) override; + virtual status_t queueBuffer( + int slot, + QueueBufferInput const& input, + QueueBufferOutput* output) override; + virtual status_t cancelBuffer(int slot, sp<Fence> const& fence) override; + virtual int query(int what, int* value) override; + virtual status_t connect( + sp<IProducerListener> const& listener, + int api, + bool producerControlledByApp, + QueueBufferOutput* output) override; + virtual status_t disconnect( + int api, + DisconnectMode mode = DisconnectMode::Api) override; + virtual status_t setSidebandStream(sp<NativeHandle> const& stream) override; + virtual void allocateBuffers( + uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage) override; + virtual status_t allowAllocation(bool allow) override; + virtual status_t setGenerationNumber(uint32_t generationNumber) override; + virtual String8 getConsumerName() const override; + virtual status_t setSharedBufferMode(bool sharedBufferMode) override; + virtual status_t setAutoRefresh(bool autoRefresh) override; + virtual status_t setDequeueTimeout(nsecs_t timeout) override; + virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence, float outTransformMatrix[16]) override; + virtual void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override; + virtual status_t getUniqueId(uint64_t* outId) const override; + virtual status_t getConsumerUsage(uint64_t* outUsage) const override; +}; + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H diff --git a/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h b/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h new file mode 100644 index 0000000000..898920bf8a --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h @@ -0,0 +1,52 @@ +/* + * Copyright 2019 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_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H + +#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h> +#include <gui/IProducerListener.h> +#include <hidl/HybridInterface.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; + +using BProducerListener = ::android::IProducerListener; + +class H2BProducerListener + : public H2BConverter<HProducerListener, BnProducerListener> { +public: + H2BProducerListener(sp<HProducerListener> const& base); + virtual void onBufferReleased() override; + virtual bool needsReleaseNotify() override; +}; + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/2.0/types.h b/libs/gui/include/gui/bufferqueue/2.0/types.h new file mode 100644 index 0000000000..62176ce2ef --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/types.h @@ -0,0 +1,129 @@ +/* + * Copyright 2019 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_BUFFERQUEUE_V2_0_TYPES_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H + +#include <android/hardware/graphics/bufferqueue/2.0/types.h> +#include <android/hardware/graphics/common/1.2/types.h> +#include <hidl/HidlSupport.h> +#include <ui/Fence.h> +#include <ui/GraphicBuffer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// Status +// ====== + +using HStatus = ::android::hardware::graphics::bufferqueue::V2_0:: + Status; + +// A status_t value may have flags encoded. These flags are decoded into boolean +// values if their corresponding output pointers are not null. +bool b2h(status_t from, HStatus* to, + bool* bufferNeedsReallocation = nullptr, + bool* releaseAllBuffers = nullptr); +// Simple 1-to-1 mapping. If BUFFER_NEEDS_REALLOCATION or RELEASE_ALL_BUFFERS +// needs to be added, it must be done manually afterwards. +bool h2b(HStatus from, status_t* to); + +// Fence +// ===== + +using BFence = ::android::Fence; +// This class manages the lifetime of a copied handle. Its destructor calls +// native_handle_delete() but not native_handle_close(). +struct HFenceWrapper { + HFenceWrapper() = default; + // Sets mHandle to a new value. + HFenceWrapper(native_handle_t* h); + // Deletes mHandle without closing. + ~HFenceWrapper(); + // Deletes mHandle without closing, then sets mHandle to a new value. + HFenceWrapper& set(native_handle_t* h); + HFenceWrapper& operator=(native_handle_t* h); + // Returns a non-owning hidl_handle pointing to mHandle. + hidl_handle getHandle() const; + operator hidl_handle() const; +protected: + native_handle_t* mHandle{nullptr}; +}; + +// Does not clone the fd---only copy the fd. The returned HFenceWrapper should +// not outlive the input Fence object. +bool b2h(sp<BFence> const& from, HFenceWrapper* to); +// Clones the fd and puts it in a new Fence object. +bool h2b(native_handle_t const* from, sp<BFence>* to); + +// ConnectionType +// ============== + +using HConnectionType = ::android::hardware::graphics::bufferqueue::V2_0:: + ConnectionType; + +bool b2h(int from, HConnectionType* to); +bool h2b(HConnectionType from, int* to); + +// Rect +// ==== + +using BRect = ::android::Rect; +using HRect = ::android::hardware::graphics::common::V1_2::Rect; + +bool b2h(BRect const& from, HRect* to); +bool h2b(HRect const& from, BRect* to); + +// Region +// ====== + +using BRegion = ::android::Region; +using HRegion = ::android::hardware::hidl_vec<HRect>; + +bool b2h(BRegion const& from, HRegion* to); +bool h2b(HRegion const& from, BRegion* to); + +// GraphicBuffer +// ============= + +using HardwareBuffer = ::android::hardware::graphics::common::V1_2:: + HardwareBuffer; +using HardwareBufferDescription = ::android::hardware::graphics::common::V1_2:: + HardwareBufferDescription; + +// Does not clone the handle. The returned HardwareBuffer should not outlive the +// input GraphicBuffer. Note that HardwareBuffer does not carry the generation +// number, so this function needs another output argument. +bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to, + uint32_t* toGenerationNumber = nullptr); +// Clones the handle and creates a new GraphicBuffer from the cloned handle. +// Note that the generation number of the GraphicBuffer has to be set manually +// afterwards because HardwareBuffer does not have such information. +bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to); + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H + diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp index 994e953e76..52fc9d5bad 100644 --- a/libs/nativewindow/AHardwareBuffer.cpp +++ b/libs/nativewindow/AHardwareBuffer.cpp @@ -636,11 +636,11 @@ uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage) { } const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) { - return reinterpret_cast<const GraphicBuffer*>(buffer); + return GraphicBuffer::fromAHardwareBuffer(buffer); } GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) { - return reinterpret_cast<GraphicBuffer*>(buffer); + return GraphicBuffer::fromAHardwareBuffer(buffer); } const ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(const AHardwareBuffer* buffer) { @@ -652,7 +652,7 @@ ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(AHardwareBuffer* buf } AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) { - return reinterpret_cast<AHardwareBuffer*>(buffer); + return buffer->toAHardwareBuffer(); } } // namespace android diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp index d8478848cb..27ab482676 100644 --- a/libs/nativewindow/Android.bp +++ b/libs/nativewindow/Android.bp @@ -24,7 +24,7 @@ ndk_headers { cc_library_headers { name: "libnativewindow_headers", export_include_dirs: ["include"], - vendor_available: false, + vendor_available: true, } ndk_library { diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index 4ca1781be1..e521b613a0 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -124,7 +124,6 @@ cc_library_shared { exclude_header_libs: [ "libbufferhub_headers", "libdvr_headers", - "libnativewindow_headers", ], exclude_shared_libs: [ "android.frameworks.bufferhub@1.0", @@ -152,6 +151,7 @@ cc_library_shared { export_header_lib_headers: [ "libbase_headers", "libnativebase_headers", + "libnativewindow_headers", "libhardware_headers", "libui_headers", ], diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 79958ece9e..f800627ef7 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -49,6 +49,22 @@ sp<GraphicBuffer> GraphicBuffer::from(ANativeWindowBuffer* anwb) { return static_cast<GraphicBuffer *>(anwb); } +GraphicBuffer* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer* buffer) { + return reinterpret_cast<GraphicBuffer*>(buffer); +} + +GraphicBuffer const* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer const* buffer) { + return reinterpret_cast<GraphicBuffer const*>(buffer); +} + +AHardwareBuffer* GraphicBuffer::toAHardwareBuffer() { + return reinterpret_cast<AHardwareBuffer*>(this); +} + +AHardwareBuffer const* GraphicBuffer::toAHardwareBuffer() const { + return reinterpret_cast<AHardwareBuffer const*>(this); +} + GraphicBuffer::GraphicBuffer() : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) diff --git a/libs/ui/include/ui/Fence.h b/libs/ui/include/ui/Fence.h index ec67fa972c..6efecd3c0e 100644 --- a/libs/ui/include/ui/Fence.h +++ b/libs/ui/include/ui/Fence.h @@ -99,6 +99,12 @@ public: // be returned and errno will indicate the problem. int dup() const; + // Return the underlying file descriptor without giving up ownership. The + // returned file descriptor is only valid for as long as the owning Fence + // object lives. (If the situation is unclear, dup() is always a safer + // option.) + int get() const { return mFenceFd.get(); } + // getSignalTime returns the system monotonic clock time at which the // fence transitioned to the signaled state. If the fence is not signaled // then SIGNAL_TIME_PENDING is returned. If the fence is invalid or if an diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h index 4d4ee68194..e0c655813d 100644 --- a/libs/ui/include/ui/GraphicBuffer.h +++ b/libs/ui/include/ui/GraphicBuffer.h @@ -22,6 +22,7 @@ #include <string> +#include <android/hardware_buffer.h> #include <ui/ANativeObjectBase.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> @@ -78,6 +79,10 @@ public: static sp<GraphicBuffer> from(ANativeWindowBuffer *); + static GraphicBuffer* fromAHardwareBuffer(AHardwareBuffer*); + static GraphicBuffer const* fromAHardwareBuffer(AHardwareBuffer const*); + AHardwareBuffer* toAHardwareBuffer(); + AHardwareBuffer const* toAHardwareBuffer() const; // Create a GraphicBuffer to be unflatten'ed into or be reallocated. GraphicBuffer(); |