/* * 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_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_ #define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_ #include #include #include #include #include #include #include #include #include namespace android { using ::android::hardware::media::V1_0::AnwBuffer; using ::android::hidl::base::V1_0::IBase; using ::android::hardware::hidl_array; using ::android::hardware::hidl_handle; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; typedef ::android::hardware::graphics::bufferqueue::V1_0:: IGraphicBufferProducer HGraphicBufferProducer; typedef ::android::hardware::graphics::bufferqueue::V1_0:: IProducerListener HProducerListener; typedef ::android::IGraphicBufferProducer BGraphicBufferProducer; typedef ::android::IProducerListener BProducerListener; #ifndef LOG struct LOG_stub { template LOG_stub& operator<<(const T&) { return *this; } }; #define LOG(x) LOG_stub() #endif // Instantiate only if HGraphicBufferProducer is base of BASE. template ::value>::type> struct TWGraphicBufferProducer : public BASE { TWGraphicBufferProducer(sp const& base) : mBase(base) {} Return requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override { sp buf; status_t status = mBase->requestBuffer(slot, &buf); AnwBuffer anwBuffer{}; if (buf != nullptr) { ::android::conversion::wrapAs(&anwBuffer, *buf); } _hidl_cb(static_cast(status), anwBuffer); return Void(); } Return setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers) override { return static_cast(mBase->setMaxDequeuedBufferCount( static_cast(maxDequeuedBuffers))); } Return setAsyncMode(bool async) override { return static_cast(mBase->setAsyncMode(async)); } Return dequeueBuffer( uint32_t width, uint32_t height, ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage, bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override { int slot{}; sp fence; ::android::FrameEventHistoryDelta outTimestamps; status_t status = mBase->dequeueBuffer( &slot, &fence, width, height, static_cast<::android::PixelFormat>(format), usage, nullptr, getFrameTimestamps ? &outTimestamps : nullptr); hidl_handle tFence{}; HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps{}; native_handle_t* nh = nullptr; if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) { LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - " "Invalid output fence"; _hidl_cb(static_cast(status), static_cast(slot), tFence, tOutTimestamps); return Void(); } std::vector > nhAA; if (getFrameTimestamps && !::android::conversion::wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) { LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - " "Invalid output timestamps"; _hidl_cb(static_cast(status), static_cast(slot), tFence, tOutTimestamps); native_handle_delete(nh); return Void(); } _hidl_cb(static_cast(status), static_cast(slot), tFence, tOutTimestamps); native_handle_delete(nh); if (getFrameTimestamps) { for (auto& nhA : nhAA) { for (auto& handle : nhA) { native_handle_delete(handle); } } } return Void(); } Return detachBuffer(int32_t slot) override { return static_cast(mBase->detachBuffer(slot)); } Return detachNextBuffer(HGraphicBufferProducer::detachNextBuffer_cb _hidl_cb) override { sp outBuffer; sp outFence; status_t status = mBase->detachNextBuffer(&outBuffer, &outFence); AnwBuffer tBuffer{}; hidl_handle tFence{}; if (outBuffer == nullptr) { LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - " "Invalid output buffer"; _hidl_cb(static_cast(status), tBuffer, tFence); return Void(); } ::android::conversion::wrapAs(&tBuffer, *outBuffer); native_handle_t* nh = nullptr; if ((outFence != nullptr) && !::android::conversion::wrapAs(&tFence, &nh, *outFence)) { LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - " "Invalid output fence"; _hidl_cb(static_cast(status), tBuffer, tFence); return Void(); } _hidl_cb(static_cast(status), tBuffer, tFence); native_handle_delete(nh); return Void(); } Return attachBuffer(const AnwBuffer& buffer, HGraphicBufferProducer::attachBuffer_cb _hidl_cb) override { int outSlot; sp lBuffer = new GraphicBuffer(); if (!::android::conversion::convertTo(lBuffer.get(), buffer)) { LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - " "Invalid input native window buffer"; _hidl_cb(static_cast(BAD_VALUE), -1); return Void(); } status_t status = mBase->attachBuffer(&outSlot, lBuffer); _hidl_cb(static_cast(status), static_cast(outSlot)); return Void(); } Return queueBuffer( int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input, HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override { HGraphicBufferProducer::QueueBufferOutput tOutput{}; BGraphicBufferProducer::QueueBufferInput lInput( 0, false, HAL_DATASPACE_UNKNOWN, ::android::Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, ::android::Fence::NO_FENCE); if (!::android::conversion::convertTo(&lInput, input)) { LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - " "Invalid input"; _hidl_cb(static_cast(BAD_VALUE), tOutput); return Void(); } BGraphicBufferProducer::QueueBufferOutput lOutput; status_t status = mBase->queueBuffer( static_cast(slot), lInput, &lOutput); std::vector > nhAA; if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) { LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - " "Invalid output"; _hidl_cb(static_cast(BAD_VALUE), tOutput); return Void(); } _hidl_cb(static_cast(status), tOutput); for (auto& nhA : nhAA) { for (auto& nh : nhA) { native_handle_delete(nh); } } return Void(); } Return cancelBuffer(int32_t slot, const hidl_handle& fence) override { sp lFence = new Fence(); if (!::android::conversion::convertTo(lFence.get(), fence)) { LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - " "Invalid input fence"; return static_cast(BAD_VALUE); } return static_cast(mBase->cancelBuffer(static_cast(slot), lFence)); } Return query(int32_t what, HGraphicBufferProducer::query_cb _hidl_cb) override { int lValue; int lReturn = mBase->query(static_cast(what), &lValue); _hidl_cb(static_cast(lReturn), static_cast(lValue)); return Void(); } Return connect(const sp& listener, int32_t api, bool producerControlledByApp, HGraphicBufferProducer::connect_cb _hidl_cb) override { sp lListener = listener == nullptr ? nullptr : new LWProducerListener(listener); BGraphicBufferProducer::QueueBufferOutput lOutput; status_t status = mBase->connect(lListener, static_cast(api), producerControlledByApp, &lOutput); HGraphicBufferProducer::QueueBufferOutput tOutput{}; std::vector > nhAA; if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) { LOG(ERROR) << "TWGraphicBufferProducer::connect - " "Invalid output"; _hidl_cb(static_cast(status), tOutput); return Void(); } _hidl_cb(static_cast(status), tOutput); for (auto& nhA : nhAA) { for (auto& nh : nhA) { native_handle_delete(nh); } } return Void(); } Return disconnect( int32_t api, HGraphicBufferProducer::DisconnectMode mode) override { return static_cast(mBase->disconnect( static_cast(api), ::android::conversion::toGuiDisconnectMode(mode))); } Return setSidebandStream(const hidl_handle& stream) override { return static_cast(mBase->setSidebandStream(NativeHandle::create( stream ? native_handle_clone(stream) : NULL, true))); } Return allocateBuffers( uint32_t width, uint32_t height, ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage) override { mBase->allocateBuffers( width, height, static_cast<::android::PixelFormat>(format), usage); return Void(); } Return allowAllocation(bool allow) override { return static_cast(mBase->allowAllocation(allow)); } Return setGenerationNumber(uint32_t generationNumber) override { return static_cast(mBase->setGenerationNumber(generationNumber)); } Return getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override { _hidl_cb(mBase->getConsumerName().string()); return Void(); } Return setSharedBufferMode(bool sharedBufferMode) override { return static_cast(mBase->setSharedBufferMode(sharedBufferMode)); } Return setAutoRefresh(bool autoRefresh) override { return static_cast(mBase->setAutoRefresh(autoRefresh)); } Return setDequeueTimeout(int64_t timeoutNs) override { return static_cast(mBase->setDequeueTimeout(timeoutNs)); } Return getLastQueuedBuffer(HGraphicBufferProducer::getLastQueuedBuffer_cb _hidl_cb) override { sp lOutBuffer = new GraphicBuffer(); sp lOutFence = new Fence(); float lOutTransformMatrix[16]; status_t status = mBase->getLastQueuedBuffer( &lOutBuffer, &lOutFence, lOutTransformMatrix); AnwBuffer tOutBuffer{}; if (lOutBuffer != nullptr) { ::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer); } hidl_handle tOutFence{}; native_handle_t* nh = nullptr; if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) { LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - " "Invalid output fence"; _hidl_cb(static_cast(status), tOutBuffer, tOutFence, hidl_array()); return Void(); } hidl_array tOutTransformMatrix(lOutTransformMatrix); _hidl_cb(static_cast(status), tOutBuffer, tOutFence, tOutTransformMatrix); native_handle_delete(nh); return Void(); } Return getFrameTimestamps(HGraphicBufferProducer::getFrameTimestamps_cb _hidl_cb) override { ::android::FrameEventHistoryDelta lDelta; mBase->getFrameTimestamps(&lDelta); HGraphicBufferProducer::FrameEventHistoryDelta tDelta{}; std::vector > nhAA; if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) { LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - " "Invalid output frame timestamps"; _hidl_cb(tDelta); return Void(); } _hidl_cb(tDelta); for (auto& nhA : nhAA) { for (auto& nh : nhA) { native_handle_delete(nh); } } return Void(); } Return getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override { uint64_t outId{}; status_t status = mBase->getUniqueId(&outId); _hidl_cb(static_cast(status), outId); return Void(); } private: sp mBase; }; } // namespace android #endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_WGRAPHICBUFFERPRODUCER_H_