| /* |
| * Copyright 2021 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 <inttypes.h> |
| #include <gui/IGraphicBufferProducer.h> |
| |
| namespace android { |
| |
| constexpr size_t IGraphicBufferProducer::QueueBufferInput::minFlattenedSize() { |
| return sizeof(timestamp) + |
| sizeof(isAutoTimestamp) + |
| sizeof(dataSpace) + |
| sizeof(crop) + |
| sizeof(scalingMode) + |
| sizeof(transform) + |
| sizeof(stickyTransform) + |
| sizeof(getFrameTimestamps) + |
| sizeof(slot); |
| } |
| |
| size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { |
| return minFlattenedSize() + |
| fence->getFlattenedSize() + |
| surfaceDamage.getFlattenedSize() + |
| hdrMetadata.getFlattenedSize(); |
| } |
| |
| size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { |
| return fence->getFdCount(); |
| } |
| |
| status_t IGraphicBufferProducer::QueueBufferInput::flatten( |
| void*& buffer, size_t& size, int*& fds, size_t& count) const |
| { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::write(buffer, size, timestamp); |
| FlattenableUtils::write(buffer, size, isAutoTimestamp); |
| FlattenableUtils::write(buffer, size, dataSpace); |
| FlattenableUtils::write(buffer, size, crop); |
| FlattenableUtils::write(buffer, size, scalingMode); |
| FlattenableUtils::write(buffer, size, transform); |
| FlattenableUtils::write(buffer, size, stickyTransform); |
| FlattenableUtils::write(buffer, size, getFrameTimestamps); |
| |
| status_t result = fence->flatten(buffer, size, fds, count); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| result = surfaceDamage.flatten(buffer, size); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| FlattenableUtils::advance(buffer, size, surfaceDamage.getFlattenedSize()); |
| result = hdrMetadata.flatten(buffer, size); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| FlattenableUtils::advance(buffer, size, hdrMetadata.getFlattenedSize()); |
| FlattenableUtils::write(buffer, size, slot); |
| return NO_ERROR; |
| } |
| |
| status_t IGraphicBufferProducer::QueueBufferInput::unflatten( |
| void const*& buffer, size_t& size, int const*& fds, size_t& count) |
| { |
| if (size < minFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::read(buffer, size, timestamp); |
| FlattenableUtils::read(buffer, size, isAutoTimestamp); |
| FlattenableUtils::read(buffer, size, dataSpace); |
| FlattenableUtils::read(buffer, size, crop); |
| FlattenableUtils::read(buffer, size, scalingMode); |
| FlattenableUtils::read(buffer, size, transform); |
| FlattenableUtils::read(buffer, size, stickyTransform); |
| FlattenableUtils::read(buffer, size, getFrameTimestamps); |
| |
| fence = new Fence(); |
| status_t result = fence->unflatten(buffer, size, fds, count); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| result = surfaceDamage.unflatten(buffer, size); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| FlattenableUtils::advance(buffer, size, surfaceDamage.getFlattenedSize()); |
| result = hdrMetadata.unflatten(buffer, size); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| FlattenableUtils::advance(buffer, size, hdrMetadata.getFlattenedSize()); |
| FlattenableUtils::read(buffer, size, slot); |
| return NO_ERROR; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| constexpr size_t IGraphicBufferProducer::QueueBufferOutput::minFlattenedSize() { |
| return sizeof(width) + sizeof(height) + sizeof(transformHint) + sizeof(numPendingBuffers) + |
| sizeof(nextFrameNumber) + sizeof(bufferReplaced) + sizeof(maxBufferCount) + |
| sizeof(result); |
| } |
| size_t IGraphicBufferProducer::QueueBufferOutput::getFlattenedSize() const { |
| return minFlattenedSize() + frameTimestamps.getFlattenedSize(); |
| } |
| |
| size_t IGraphicBufferProducer::QueueBufferOutput::getFdCount() const { |
| return frameTimestamps.getFdCount(); |
| } |
| |
| status_t IGraphicBufferProducer::QueueBufferOutput::flatten( |
| void*& buffer, size_t& size, int*& fds, size_t& count) const |
| { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::write(buffer, size, width); |
| FlattenableUtils::write(buffer, size, height); |
| FlattenableUtils::write(buffer, size, transformHint); |
| FlattenableUtils::write(buffer, size, numPendingBuffers); |
| FlattenableUtils::write(buffer, size, nextFrameNumber); |
| FlattenableUtils::write(buffer, size, bufferReplaced); |
| FlattenableUtils::write(buffer, size, maxBufferCount); |
| |
| status_t result = frameTimestamps.flatten(buffer, size, fds, count); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| FlattenableUtils::write(buffer, size, result); |
| return NO_ERROR; |
| } |
| |
| status_t IGraphicBufferProducer::QueueBufferOutput::unflatten( |
| void const*& buffer, size_t& size, int const*& fds, size_t& count) |
| { |
| if (size < minFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::read(buffer, size, width); |
| FlattenableUtils::read(buffer, size, height); |
| FlattenableUtils::read(buffer, size, transformHint); |
| FlattenableUtils::read(buffer, size, numPendingBuffers); |
| FlattenableUtils::read(buffer, size, nextFrameNumber); |
| FlattenableUtils::read(buffer, size, bufferReplaced); |
| FlattenableUtils::read(buffer, size, maxBufferCount); |
| |
| status_t result = frameTimestamps.unflatten(buffer, size, fds, count); |
| if (result != NO_ERROR) { |
| return result; |
| } |
| FlattenableUtils::read(buffer, size, result); |
| return NO_ERROR; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| constexpr size_t IGraphicBufferProducer::RequestBufferOutput::minFlattenedSize() { |
| return sizeof(result) + |
| sizeof(int32_t); // IsBufferNull |
| } |
| |
| size_t IGraphicBufferProducer::RequestBufferOutput::getFlattenedSize() const { |
| return minFlattenedSize() + (buffer == nullptr ? 0 : buffer->getFlattenedSize()); |
| } |
| |
| size_t IGraphicBufferProducer::RequestBufferOutput::getFdCount() const { |
| return (buffer == nullptr ? 0 : buffer->getFdCount()); |
| } |
| |
| status_t IGraphicBufferProducer::RequestBufferOutput::flatten( |
| void*& fBuffer, size_t& size, int*& fds, size_t& count) const { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::write(fBuffer, size, result); |
| const int32_t isBufferNull = (buffer == nullptr ? 1 : 0); |
| FlattenableUtils::write(fBuffer, size, isBufferNull); |
| |
| if (!isBufferNull) { |
| status_t status = buffer->flatten(fBuffer, size, fds, count); |
| if (status != NO_ERROR) { |
| return status; |
| } |
| } |
| return NO_ERROR; |
| } |
| |
| status_t IGraphicBufferProducer::RequestBufferOutput::unflatten( |
| void const*& fBuffer, size_t& size, int const*& fds, size_t& count) { |
| if (size < minFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::read(fBuffer, size, result); |
| int32_t isBufferNull = 0; |
| FlattenableUtils::read(fBuffer, size, isBufferNull); |
| buffer = new GraphicBuffer(); |
| if (!isBufferNull) { |
| status_t status = buffer->unflatten(fBuffer, size, fds, count); |
| if (status != NO_ERROR) { |
| return status; |
| } |
| } |
| return NO_ERROR; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| size_t IGraphicBufferProducer::DequeueBufferInput::getFlattenedSize() const { |
| return sizeof(width) + sizeof(height) + sizeof(format) + sizeof(usage) + |
| sizeof(int32_t/*getTimestamps*/); |
| } |
| |
| status_t IGraphicBufferProducer::DequeueBufferInput::flatten(void* buffer, size_t size) const { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| FlattenableUtils::write(buffer, size, width); |
| FlattenableUtils::write(buffer, size, height); |
| FlattenableUtils::write(buffer, size, format); |
| FlattenableUtils::write(buffer, size, usage); |
| const int32_t getTimestampsInt = (getTimestamps ? 1 : 0); |
| FlattenableUtils::write(buffer, size, getTimestampsInt); |
| |
| return NO_ERROR; |
| } |
| |
| status_t IGraphicBufferProducer::DequeueBufferInput::unflatten(void const* buffer, size_t size) { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::read(buffer, size, width); |
| FlattenableUtils::read(buffer, size, height); |
| FlattenableUtils::read(buffer, size, format); |
| FlattenableUtils::read(buffer, size, usage); |
| int32_t getTimestampsInt = 0; |
| FlattenableUtils::read(buffer, size, getTimestampsInt); |
| getTimestamps = (getTimestampsInt == 1); |
| |
| return NO_ERROR; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| constexpr size_t IGraphicBufferProducer::DequeueBufferOutput::minFlattenedSize() { |
| return sizeof(result) + sizeof(slot) + sizeof(bufferAge) + sizeof(int32_t/*hasTimestamps*/); |
| } |
| |
| size_t IGraphicBufferProducer::DequeueBufferOutput::getFlattenedSize() const { |
| return minFlattenedSize() + |
| fence->getFlattenedSize() + |
| (timestamps.has_value() ? timestamps->getFlattenedSize() : 0); |
| } |
| |
| size_t IGraphicBufferProducer::DequeueBufferOutput::getFdCount() const { |
| return fence->getFdCount() + |
| (timestamps.has_value() ? timestamps->getFdCount() : 0); |
| } |
| |
| status_t IGraphicBufferProducer::DequeueBufferOutput::flatten( |
| void*& buffer, size_t& size, int*& fds, size_t& count) const { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::write(buffer, size, result); |
| FlattenableUtils::write(buffer, size, slot); |
| FlattenableUtils::write(buffer, size, bufferAge); |
| status_t status = fence->flatten(buffer, size, fds, count); |
| if (status != NO_ERROR) { |
| return result; |
| } |
| const int32_t hasTimestamps = timestamps.has_value() ? 1 : 0; |
| FlattenableUtils::write(buffer, size, hasTimestamps); |
| if (timestamps.has_value()) { |
| status = timestamps->flatten(buffer, size, fds, count); |
| } |
| return status; |
| } |
| |
| status_t IGraphicBufferProducer::DequeueBufferOutput::unflatten( |
| void const*& buffer, size_t& size, int const*& fds, size_t& count) { |
| if (size < minFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::read(buffer, size, result); |
| FlattenableUtils::read(buffer, size, slot); |
| FlattenableUtils::read(buffer, size, bufferAge); |
| |
| fence = new Fence(); |
| status_t status = fence->unflatten(buffer, size, fds, count); |
| if (status != NO_ERROR) { |
| return status; |
| } |
| int32_t hasTimestamps = 0; |
| FlattenableUtils::read(buffer, size, hasTimestamps); |
| if (hasTimestamps) { |
| timestamps.emplace(); |
| status = timestamps->unflatten(buffer, size, fds, count); |
| } |
| return status; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| size_t IGraphicBufferProducer::AttachBufferOutput::getFlattenedSize() const { |
| return sizeof(result) + sizeof(slot); |
| } |
| |
| status_t IGraphicBufferProducer::AttachBufferOutput::flatten(void* buffer, size_t size) const { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| FlattenableUtils::write(buffer, size, result); |
| FlattenableUtils::write(buffer, size, slot); |
| |
| return NO_ERROR; |
| } |
| |
| status_t IGraphicBufferProducer::AttachBufferOutput::unflatten(void const* buffer, size_t size) { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| FlattenableUtils::read(buffer, size, result); |
| FlattenableUtils::read(buffer, size, slot); |
| |
| return NO_ERROR; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| constexpr size_t IGraphicBufferProducer::CancelBufferInput::minFlattenedSize() { |
| return sizeof(slot); |
| } |
| |
| size_t IGraphicBufferProducer::CancelBufferInput::getFlattenedSize() const { |
| return minFlattenedSize() + fence->getFlattenedSize(); |
| } |
| |
| size_t IGraphicBufferProducer::CancelBufferInput::getFdCount() const { |
| return fence->getFdCount(); |
| } |
| |
| status_t IGraphicBufferProducer::CancelBufferInput::flatten( |
| void*& buffer, size_t& size, int*& fds, size_t& count) const { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::write(buffer, size, slot); |
| return fence->flatten(buffer, size, fds, count); |
| } |
| |
| status_t IGraphicBufferProducer::CancelBufferInput::unflatten( |
| void const*& buffer, size_t& size, int const*& fds, size_t& count) { |
| if (size < minFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| |
| FlattenableUtils::read(buffer, size, slot); |
| |
| fence = new Fence(); |
| return fence->unflatten(buffer, size, fds, count); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| |
| size_t IGraphicBufferProducer::QueryOutput::getFlattenedSize() const { |
| return sizeof(result) + sizeof(value); |
| } |
| |
| status_t IGraphicBufferProducer::QueryOutput::flatten(void* buffer, size_t size) const { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| FlattenableUtils::write(buffer, size, result); |
| FlattenableUtils::write(buffer, size, value); |
| |
| return NO_ERROR; |
| } |
| |
| status_t IGraphicBufferProducer::QueryOutput::unflatten(void const* buffer, size_t size) { |
| if (size < getFlattenedSize()) { |
| return NO_MEMORY; |
| } |
| FlattenableUtils::read(buffer, size, result); |
| FlattenableUtils::read(buffer, size, value); |
| |
| return NO_ERROR; |
| } |
| |
| } // namespace android |