diff options
Diffstat (limited to 'libs/gui')
42 files changed, 1309 insertions, 854 deletions
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index ca94aa3..8a965dd 100644 --- a/libs/gui/Android.mk +++ b/libs/gui/Android.mk @@ -1,7 +1,42 @@ -LOCAL_PATH:= $(call my-dir) +# Copyright 2010 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. + +LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES:= \ +LOCAL_CLANG := true +LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror + +# The static constructors and destructors in this library have not been noted to +# introduce significant overheads +LOCAL_CPPFLAGS += -Wno-exit-time-destructors +LOCAL_CPPFLAGS += -Wno-global-constructors + +# We only care about compiling as C++14 +LOCAL_CPPFLAGS += -Wno-c++98-compat-pedantic + +# We don't need to enumerate every case in a switch as long as a default case +# is present +LOCAL_CPPFLAGS += -Wno-switch-enum + +# Allow calling variadic macros without a __VA_ARGS__ list +LOCAL_CPPFLAGS += -Wno-gnu-zero-variadic-macro-arguments + +# Don't warn about struct padding +LOCAL_CPPFLAGS += -Wno-padded + +LOCAL_SRC_FILES := \ IGraphicBufferConsumer.cpp \ IConsumerListener.cpp \ BitTube.cpp \ @@ -47,7 +82,7 @@ LOCAL_SHARED_LIBRARIES := \ liblog -LOCAL_MODULE:= libgui +LOCAL_MODULE := libgui ifeq ($(TARGET_BOARD_PLATFORM), tegra) LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp index 3ed1f37..b653c5b 100644 --- a/libs/gui/BitTube.cpp +++ b/libs/gui/BitTube.cpp @@ -149,12 +149,12 @@ ssize_t BitTube::sendObjects(const sp<BitTube>& tube, ssize_t size = tube->write(vaddr, count*objSize); // should never happen because of SOCK_SEQPACKET - LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize), + LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)), "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)", count, objSize, size); //ALOGE_IF(size<0, "error %d sending %d events", size, count); - return size < 0 ? size : size / objSize; + return size < 0 ? size : size / static_cast<ssize_t>(objSize); } ssize_t BitTube::recvObjects(const sp<BitTube>& tube, @@ -164,12 +164,12 @@ ssize_t BitTube::recvObjects(const sp<BitTube>& tube, ssize_t size = tube->read(vaddr, count*objSize); // should never happen because of SOCK_SEQPACKET - LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize), + LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)), "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)", count, objSize, size); //ALOGE_IF(size<0, "error %d receiving %d events", size, count); - return size < 0 ? size : size / objSize; + return size < 0 ? size : size / static_cast<ssize_t>(objSize); } // ---------------------------------------------------------------------------- diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index e6fc791..5793d40 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -28,6 +28,7 @@ BufferItem::BufferItem() : mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mTimestamp(0), mIsAutoTimestamp(false), + mDataSpace(HAL_DATASPACE_UNKNOWN), mFrameNumber(0), mSlot(INVALID_BUFFER_SLOT), mIsDroppable(false), @@ -38,66 +39,66 @@ BufferItem::BufferItem() : BufferItem::~BufferItem() {} -BufferItem::operator IGraphicBufferConsumer::BufferItem() const { - IGraphicBufferConsumer::BufferItem bufferItem; - bufferItem.mGraphicBuffer = mGraphicBuffer; - bufferItem.mFence = mFence; - bufferItem.mCrop = mCrop; - bufferItem.mTransform = mTransform; - bufferItem.mScalingMode = mScalingMode; - bufferItem.mTimestamp = mTimestamp; - bufferItem.mIsAutoTimestamp = mIsAutoTimestamp; - bufferItem.mFrameNumber = mFrameNumber; - bufferItem.mBuf = mSlot; - bufferItem.mIsDroppable = mIsDroppable; - bufferItem.mAcquireCalled = mAcquireCalled; - bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse; - return bufferItem; +template <typename T> +static void addAligned(size_t& size, T /* value */) { + size = FlattenableUtils::align<sizeof(T)>(size); + size += sizeof(T); } size_t BufferItem::getPodSize() const { - size_t c = sizeof(mCrop) + - sizeof(mTransform) + - sizeof(mScalingMode) + - sizeof(mTimestamp) + - sizeof(mIsAutoTimestamp) + - sizeof(mFrameNumber) + - sizeof(mSlot) + - sizeof(mIsDroppable) + - sizeof(mAcquireCalled) + - sizeof(mTransformToDisplayInverse); - return c; + // Must align<8> before writing these fields for this to be correct + size_t size = 0; + addAligned(size, mCrop); + addAligned(size, mTransform); + addAligned(size, mScalingMode); + addAligned(size, mTimestamp); + addAligned(size, mIsAutoTimestamp); + addAligned(size, mDataSpace); + addAligned(size, mFrameNumber); + addAligned(size, mSlot); + addAligned(size, mIsDroppable); + addAligned(size, mAcquireCalled); + addAligned(size, mTransformToDisplayInverse); + return size; } size_t BufferItem::getFlattenedSize() const { - size_t c = 0; + size_t size = sizeof(uint32_t); // Flags if (mGraphicBuffer != 0) { - c += mGraphicBuffer->getFlattenedSize(); - FlattenableUtils::align<4>(c); + size += mGraphicBuffer->getFlattenedSize(); + FlattenableUtils::align<4>(size); } if (mFence != 0) { - c += mFence->getFlattenedSize(); - FlattenableUtils::align<4>(c); + size += mFence->getFlattenedSize(); + FlattenableUtils::align<4>(size); } - return sizeof(int32_t) + c + getPodSize(); + size += mSurfaceDamage.getFlattenedSize(); + size = FlattenableUtils::align<8>(size); + return size + getPodSize(); } size_t BufferItem::getFdCount() const { - size_t c = 0; + size_t count = 0; if (mGraphicBuffer != 0) { - c += mGraphicBuffer->getFdCount(); + count += mGraphicBuffer->getFdCount(); } if (mFence != 0) { - c += mFence->getFdCount(); + count += mFence->getFdCount(); } - return c; + return count; +} + +template <typename T> +static void writeAligned(void*& buffer, size_t& size, T value) { + size -= FlattenableUtils::align<alignof(T)>(buffer); + FlattenableUtils::write(buffer, size, value); } status_t BufferItem::flatten( void*& buffer, size_t& size, int*& fds, size_t& count) const { // make sure we have enough space - if (count < BufferItem::getFlattenedSize()) { + if (size < BufferItem::getFlattenedSize()) { return NO_MEMORY; } @@ -121,30 +122,45 @@ status_t BufferItem::flatten( flags |= 2; } - // check we have enough space (in case flattening the fence/graphicbuffer lied to us) + status_t err = mSurfaceDamage.flatten(buffer, size); + if (err) return err; + FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize()); + + // Must align<8> so that getPodSize returns the correct value + size -= FlattenableUtils::align<8>(buffer); + + // Check we still have enough space if (size < getPodSize()) { return NO_MEMORY; } - FlattenableUtils::write(buffer, size, mCrop); - FlattenableUtils::write(buffer, size, mTransform); - FlattenableUtils::write(buffer, size, mScalingMode); - FlattenableUtils::write(buffer, size, mTimestamp); - FlattenableUtils::write(buffer, size, mIsAutoTimestamp); - FlattenableUtils::write(buffer, size, mFrameNumber); - FlattenableUtils::write(buffer, size, mSlot); - FlattenableUtils::write(buffer, size, mIsDroppable); - FlattenableUtils::write(buffer, size, mAcquireCalled); - FlattenableUtils::write(buffer, size, mTransformToDisplayInverse); + writeAligned(buffer, size, mCrop); + writeAligned(buffer, size, mTransform); + writeAligned(buffer, size, mScalingMode); + writeAligned(buffer, size, mTimestamp); + writeAligned(buffer, size, mIsAutoTimestamp); + writeAligned(buffer, size, mDataSpace); + writeAligned(buffer, size, mFrameNumber); + writeAligned(buffer, size, mSlot); + writeAligned(buffer, size, mIsDroppable); + writeAligned(buffer, size, mAcquireCalled); + writeAligned(buffer, size, mTransformToDisplayInverse); return NO_ERROR; } +template <typename T> +static void readAligned(const void*& buffer, size_t& size, T& value) { + size -= FlattenableUtils::align<alignof(T)>(buffer); + FlattenableUtils::read(buffer, size, value); +} + status_t BufferItem::unflatten( void const*& buffer, size_t& size, int const*& fds, size_t& count) { - if (size < sizeof(uint32_t)) + if (size < sizeof(uint32_t)) { return NO_MEMORY; + } uint32_t flags = 0; FlattenableUtils::read(buffer, size, flags); @@ -163,21 +179,29 @@ status_t BufferItem::unflatten( size -= FlattenableUtils::align<4>(buffer); } - // check we have enough space + status_t err = mSurfaceDamage.unflatten(buffer, size); + if (err) return err; + FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize()); + + // Must align<8> so that getPodSize returns the correct value + size -= FlattenableUtils::align<8>(buffer); + + // Check we still have enough space if (size < getPodSize()) { return NO_MEMORY; } - FlattenableUtils::read(buffer, size, mCrop); - FlattenableUtils::read(buffer, size, mTransform); - FlattenableUtils::read(buffer, size, mScalingMode); - FlattenableUtils::read(buffer, size, mTimestamp); - FlattenableUtils::read(buffer, size, mIsAutoTimestamp); - FlattenableUtils::read(buffer, size, mFrameNumber); - FlattenableUtils::read(buffer, size, mSlot); - FlattenableUtils::read(buffer, size, mIsDroppable); - FlattenableUtils::read(buffer, size, mAcquireCalled); - FlattenableUtils::read(buffer, size, mTransformToDisplayInverse); + readAligned(buffer, size, mCrop); + readAligned(buffer, size, mTransform); + readAligned(buffer, size, mScalingMode); + readAligned(buffer, size, mTimestamp); + readAligned(buffer, size, mIsAutoTimestamp); + readAligned(buffer, size, mDataSpace); + readAligned(buffer, size, mFrameNumber); + readAligned(buffer, size, mSlot); + readAligned(buffer, size, mIsDroppable); + readAligned(buffer, size, mAcquireCalled); + readAligned(buffer, size, mTransformToDisplayInverse); return NO_ERROR; } diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index fe50c55..194121f 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -16,16 +16,17 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "BufferItemConsumer" -#define ATRACE_TAG ATRACE_TAG_GRAPHICS +//#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <utils/Log.h> +#include <gui/BufferItem.h> #include <gui/BufferItemConsumer.h> -#define BI_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) +//#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) +#define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) namespace android { @@ -44,8 +45,7 @@ BufferItemConsumer::BufferItemConsumer( } } -BufferItemConsumer::~BufferItemConsumer() { -} +BufferItemConsumer::~BufferItemConsumer() {} void BufferItemConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); @@ -105,9 +105,15 @@ status_t BufferItemConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) { return mConsumer->setDefaultBufferSize(w, h); } -status_t BufferItemConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { +status_t BufferItemConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { Mutex::Autolock _l(mMutex); return mConsumer->setDefaultBufferFormat(defaultFormat); } +status_t BufferItemConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + Mutex::Autolock _l(mMutex); + return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); +} + } // namespace android diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 61fd8c4..2fcbaf2 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -32,7 +32,7 @@ BufferQueue::ProxyConsumerListener::ProxyConsumerListener( BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} void BufferQueue::ProxyConsumerListener::onFrameAvailable( - const android::BufferItem& item) { + const BufferItem& item) { sp<ConsumerListener> listener(mConsumerListener.promote()); if (listener != NULL) { listener->onFrameAvailable(item); diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 36e3c06..c7d5e00 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -120,6 +120,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, if (mCore->stillTracking(front)) { // Front buffer is still in mSlots, so mark the slot as free mSlots[front->mSlot].mBufferState = BufferSlot::FREE; + mCore->mFreeBuffers.push_back(front->mSlot); } mCore->mQueue.erase(front); front = mCore->mQueue.begin(); @@ -173,6 +174,8 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); + mCore->validateConsistencyLocked(); + return NO_ERROR; } @@ -199,6 +202,7 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { mCore->freeBufferLocked(slot); mCore->mDequeueCondition.broadcast(); + mCore->validateConsistencyLocked(); return NO_ERROR; } @@ -217,18 +221,11 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, Mutex::Autolock lock(mCore->mMutex); - // Make sure we don't have too many acquired buffers and find a free slot - // to put the buffer into (the oldest if there are multiple). + // Make sure we don't have too many acquired buffers int numAcquiredBuffers = 0; - int found = BufferQueueCore::INVALID_BUFFER_SLOT; for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) { ++numAcquiredBuffers; - } else if (mSlots[s].mBufferState == BufferSlot::FREE) { - if (found == BufferQueueCore::INVALID_BUFFER_SLOT || - mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { - found = s; - } } } @@ -238,6 +235,17 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, mCore->mMaxAcquiredBufferCount); return INVALID_OPERATION; } + + // Find a free slot to put the buffer into + int found = BufferQueueCore::INVALID_BUFFER_SLOT; + if (!mCore->mFreeSlots.empty()) { + auto slot = mCore->mFreeSlots.begin(); + found = *slot; + mCore->mFreeSlots.erase(slot); + } else if (!mCore->mFreeBuffers.empty()) { + found = mCore->mFreeBuffers.front(); + mCore->mFreeBuffers.remove(found); + } if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { BQ_LOGE("attachBuffer(P): could not find free buffer slot"); return NO_MEMORY; @@ -271,6 +279,8 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, // for attached buffers. mSlots[*outSlot].mAcquireCalled = false; + mCore->validateConsistencyLocked(); + return NO_ERROR; } @@ -311,6 +321,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, mSlots[slot].mEglFence = eglFence; mSlots[slot].mFence = releaseFence; mSlots[slot].mBufferState = BufferSlot::FREE; + mCore->mFreeBuffers.push_back(slot); listener = mCore->mConnectedProducerListener; BQ_LOGV("releaseBuffer: releasing slot %d", slot); } else if (mSlots[slot].mNeedsCleanupOnRelease) { @@ -325,6 +336,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, } mCore->mDequeueCondition.broadcast(); + mCore->validateConsistencyLocked(); } // Autolock scope // Call back without lock held @@ -488,7 +500,7 @@ void BufferQueueConsumer::setConsumerName(const String8& name) { mConsumerName = name; } -status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { +status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { ATRACE_CALL(); BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat); Mutex::Autolock lock(mCore->mMutex); @@ -496,6 +508,15 @@ status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { return NO_ERROR; } +status_t BufferQueueConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + ATRACE_CALL(); + BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace); + Mutex::Autolock lock(mCore->mMutex); + mCore->mDefaultBufferDataSpace = defaultDataSpace; + return NO_ERROR; +} + status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) { ATRACE_CALL(); BQ_LOGV("setConsumerUsageBits: %#x", usage); diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index ec1e631..bc75ca7 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -53,6 +53,8 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : mConnectedProducerListener(), mSlots(), mQueue(), + mFreeSlots(), + mFreeBuffers(), mOverrideMaxBufferCount(0), mDequeueCondition(), mUseAsyncBuffer(true), @@ -60,13 +62,15 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), mDefaultWidth(1), mDefaultHeight(1), + mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN), mDefaultMaxBufferCount(2), mMaxAcquiredBufferCount(1), mBufferHasBeenQueued(false), mFrameCounter(0), mTransformHint(0), mIsAllocating(false), - mIsAllocatingCondition() + mIsAllocatingCondition(), + mAllowAllocation(true) { if (allocator == NULL) { sp<ISurfaceComposer> composer(ComposerService::getComposerService()); @@ -75,6 +79,9 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : BQ_LOGE("createGraphicBufferAlloc failed"); } } + for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { + mFreeSlots.insert(slot); + } } BufferQueueCore::~BufferQueueCore() {} @@ -189,12 +196,20 @@ status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) { void BufferQueueCore::freeBufferLocked(int slot) { BQ_LOGV("freeBufferLocked: slot %d", slot); + bool hadBuffer = mSlots[slot].mGraphicBuffer != NULL; mSlots[slot].mGraphicBuffer.clear(); if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { mSlots[slot].mNeedsCleanupOnRelease = true; } + if (mSlots[slot].mBufferState != BufferSlot::FREE) { + mFreeSlots.insert(slot); + } else if (hadBuffer) { + // If the slot was FREE, but we had a buffer, we need to move this slot + // from the free buffers list to the the free slots list + mFreeBuffers.remove(slot); + mFreeSlots.insert(slot); + } mSlots[slot].mBufferState = BufferSlot::FREE; - mSlots[slot].mFrameNumber = UINT32_MAX; mSlots[slot].mAcquireCalled = false; // Destroy fence as BufferQueue now takes ownership @@ -203,6 +218,7 @@ void BufferQueueCore::freeBufferLocked(int slot) { mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; } mSlots[slot].mFence = Fence::NO_FENCE; + validateConsistencyLocked(); } void BufferQueueCore::freeAllBuffersLocked() { @@ -235,4 +251,48 @@ void BufferQueueCore::waitWhileAllocatingLocked() const { } } +void BufferQueueCore::validateConsistencyLocked() const { + static const useconds_t PAUSE_TIME = 0; + for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { + bool isInFreeSlots = mFreeSlots.count(slot) != 0; + bool isInFreeBuffers = + std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) != + mFreeBuffers.cend(); + if (mSlots[slot].mBufferState == BufferSlot::FREE) { + if (mSlots[slot].mGraphicBuffer == NULL) { + if (!isInFreeSlots) { + BQ_LOGE("Slot %d is FREE but is not in mFreeSlots", slot); + usleep(PAUSE_TIME); + } + if (isInFreeBuffers) { + BQ_LOGE("Slot %d is in mFreeSlots " + "but is also in mFreeBuffers", slot); + usleep(PAUSE_TIME); + } + } else { + if (!isInFreeBuffers) { + BQ_LOGE("Slot %d is FREE but is not in mFreeBuffers", slot); + usleep(PAUSE_TIME); + } + if (isInFreeSlots) { + BQ_LOGE("Slot %d is in mFreeBuffers " + "but is also in mFreeSlots", slot); + usleep(PAUSE_TIME); + } + } + } else { + if (isInFreeSlots) { + BQ_LOGE("Slot %d is in mFreeSlots but is not FREE (%d)", + slot, mSlots[slot].mBufferState); + usleep(PAUSE_TIME); + } + if (isInFreeBuffers) { + BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE (%d)", + slot, mSlots[slot].mBufferState); + usleep(PAUSE_TIME); + } + } + } +} + } // namespace android diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 16b9747..86e45c8 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -161,8 +161,6 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, } } - // Look for a free buffer to give to the client - *found = BufferQueueCore::INVALID_BUFFER_SLOT; int dequeuedCount = 0; int acquiredCount = 0; for (int s = 0; s < maxBufferCount; ++s) { @@ -173,15 +171,6 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, case BufferSlot::ACQUIRED: ++acquiredCount; break; - case BufferSlot::FREE: - // We return the oldest of the free buffers to avoid - // stalling the producer if possible, since the consumer - // may still have pending reads of in-flight buffers - if (*found == BufferQueueCore::INVALID_BUFFER_SLOT || - mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) { - *found = s; - } - break; default: break; } @@ -214,6 +203,8 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, } } + *found = BufferQueueCore::INVALID_BUFFER_SLOT; + // If we disconnect and reconnect quickly, we can be in a state where // our slots are empty but we have many buffers in the queue. This can // cause us to run out of memory if we outrun the consumer. Wait here if @@ -223,6 +214,19 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, if (tooManyBuffers) { BQ_LOGV("%s: queue size is %zu, waiting", caller, mCore->mQueue.size()); + } else { + if (!mCore->mFreeBuffers.empty()) { + auto slot = mCore->mFreeBuffers.begin(); + *found = *slot; + mCore->mFreeBuffers.erase(slot); + } else if (mCore->mAllowAllocation && !mCore->mFreeSlots.empty()) { + auto slot = mCore->mFreeSlots.begin(); + // Only return free slots up to the max buffer count + if (*slot < maxBufferCount) { + *found = *slot; + mCore->mFreeSlots.erase(slot); + } + } } // If no buffer is found, or if the queue has too many buffers @@ -250,7 +254,7 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, status_t BufferQueueProducer::dequeueBuffer(int *outSlot, sp<android::Fence> *outFence, bool async, - uint32_t width, uint32_t height, uint32_t format, uint32_t usage) { + uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) { ATRACE_CALL(); { // Autolock scope Mutex::Autolock lock(mCore->mMutex); @@ -281,17 +285,39 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, // Enable the usage bits the consumer requested usage |= mCore->mConsumerUsageBits; - int found; - status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async, - &found, &returnFlags); - if (status != NO_ERROR) { - return status; + const bool useDefaultSize = !width && !height; + if (useDefaultSize) { + width = mCore->mDefaultWidth; + height = mCore->mDefaultHeight; } - // This should not happen - if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { - BQ_LOGE("dequeueBuffer: no available buffer slots"); - return -EBUSY; + int found = BufferItem::INVALID_BUFFER_SLOT; + while (found == BufferItem::INVALID_BUFFER_SLOT) { + status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async, + &found, &returnFlags); + if (status != NO_ERROR) { + return status; + } + + // This should not happen + if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { + BQ_LOGE("dequeueBuffer: no available buffer slots"); + return -EBUSY; + } + + const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); + + // If we are not allowed to allocate new buffers, + // waitForFreeSlotThenRelock must have returned a slot containing a + // buffer. If this buffer would require reallocation to meet the + // requested attributes, we free it and attempt to get another one. + if (!mCore->mAllowAllocation) { + if (buffer->needsReallocation(width, height, format, usage)) { + mCore->freeBufferLocked(found); + found = BufferItem::INVALID_BUFFER_SLOT; + continue; + } + } } *outSlot = found; @@ -299,20 +325,11 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, attachedByConsumer = mSlots[found].mAttachedByConsumer; - const bool useDefaultSize = !width && !height; - if (useDefaultSize) { - width = mCore->mDefaultWidth; - height = mCore->mDefaultHeight; - } - mSlots[found].mBufferState = BufferSlot::DEQUEUED; const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); if ((buffer == NULL) || - (static_cast<uint32_t>(buffer->width) != width) || - (static_cast<uint32_t>(buffer->height) != height) || - (static_cast<uint32_t>(buffer->format) != format) || - ((static_cast<uint32_t>(buffer->usage) & usage) != usage)) + buffer->needsReallocation(width, height, format, usage)) { mSlots[found].mAcquireCalled = false; mSlots[found].mGraphicBuffer = NULL; @@ -335,13 +352,15 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, *outFence = mSlots[found].mFence; mSlots[found].mEglFence = EGL_NO_SYNC_KHR; mSlots[found].mFence = Fence::NO_FENCE; + + mCore->validateConsistencyLocked(); } // Autolock scope if (returnFlags & BUFFER_NEEDS_REALLOCATION) { status_t error; BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( - width, height, format, usage, &error)); + width, height, format, usage, &error)); if (graphicBuffer == NULL) { BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); return error; @@ -355,7 +374,6 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, return NO_INIT; } - mSlots[*outSlot].mFrameNumber = UINT32_MAX; mSlots[*outSlot].mGraphicBuffer = graphicBuffer; } // Autolock scope } @@ -414,6 +432,7 @@ status_t BufferQueueProducer::detachBuffer(int slot) { mCore->freeBufferLocked(slot); mCore->mDequeueCondition.broadcast(); + mCore->validateConsistencyLocked(); return NO_ERROR; } @@ -438,27 +457,19 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, return NO_INIT; } - // Find the oldest valid slot - int found = BufferQueueCore::INVALID_BUFFER_SLOT; - for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { - if (mSlots[s].mBufferState == BufferSlot::FREE && - mSlots[s].mGraphicBuffer != NULL) { - if (found == BufferQueueCore::INVALID_BUFFER_SLOT || - mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { - found = s; - } - } - } - - if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { + if (mCore->mFreeBuffers.empty()) { return NO_MEMORY; } + int found = mCore->mFreeBuffers.front(); + mCore->mFreeBuffers.remove(found); + BQ_LOGV("detachNextBuffer detached slot %d", found); *outBuffer = mSlots[found].mGraphicBuffer; *outFence = mSlots[found].mFence; mCore->freeBufferLocked(found); + mCore->validateConsistencyLocked(); return NO_ERROR; } @@ -506,6 +517,8 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot, mSlots[*outSlot].mFence = Fence::NO_FENCE; mSlots[*outSlot].mRequestBufferCalled = true; + mCore->validateConsistencyLocked(); + return returnFlags; } @@ -516,14 +529,16 @@ status_t BufferQueueProducer::queueBuffer(int slot, int64_t timestamp; bool isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; uint32_t stickyTransform; bool async; sp<Fence> fence; - input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, - &async, &fence, &stickyTransform); + input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode, + &transform, &async, &fence, &stickyTransform); + Region surfaceDamage = input.getSurfaceDamage(); if (fence == NULL) { BQ_LOGE("queueBuffer: fence is NULL"); @@ -579,11 +594,11 @@ status_t BufferQueueProducer::queueBuffer(int slot, return BAD_VALUE; } - BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 + BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d" " crop=[%d,%d,%d,%d] transform=%#x scale=%s", - slot, mCore->mFrameCounter + 1, timestamp, - crop.left, crop.top, crop.right, crop.bottom, - transform, BufferItem::scalingModeName(scalingMode)); + slot, mCore->mFrameCounter + 1, timestamp, dataSpace, + crop.left, crop.top, crop.right, crop.bottom, transform, + BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode))); const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); @@ -595,6 +610,11 @@ status_t BufferQueueProducer::queueBuffer(int slot, return BAD_VALUE; } + // Override UNKNOWN dataspace with consumer default + if (dataSpace == HAL_DATASPACE_UNKNOWN) { + dataSpace = mCore->mDefaultBufferDataSpace; + } + mSlots[slot].mFence = fence; mSlots[slot].mBufferState = BufferSlot::QUEUED; ++mCore->mFrameCounter; @@ -603,16 +623,19 @@ status_t BufferQueueProducer::queueBuffer(int slot, item.mAcquireCalled = mSlots[slot].mAcquireCalled; item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; item.mCrop = crop; - item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; + item.mTransform = transform & + ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); item.mTransformToDisplayInverse = - bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); - item.mScalingMode = scalingMode; + (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; + item.mScalingMode = static_cast<uint32_t>(scalingMode); item.mTimestamp = timestamp; item.mIsAutoTimestamp = isAutoTimestamp; + item.mDataSpace = dataSpace; item.mFrameNumber = mCore->mFrameCounter; item.mSlot = slot; item.mFence = fence; item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async; + item.mSurfaceDamage = surfaceDamage; mStickyTransform = stickyTransform; @@ -630,9 +653,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, // mark it as freed if (mCore->stillTracking(front)) { mSlots[front->mSlot].mBufferState = BufferSlot::FREE; - // Reset the frame number of the freed buffer so that it is - // the first in line to be dequeued again - mSlots[front->mSlot].mFrameNumber = 0; + mCore->mFreeBuffers.push_front(front->mSlot); } // Overwrite the droppable buffer with the incoming one *front = item; @@ -647,12 +668,15 @@ status_t BufferQueueProducer::queueBuffer(int slot, mCore->mDequeueCondition.broadcast(); output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, - mCore->mTransformHint, mCore->mQueue.size()); + mCore->mTransformHint, + static_cast<uint32_t>(mCore->mQueue.size())); ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); // Take a ticket for the callback functions callbackTicket = mNextCallbackTicket++; + + mCore->validateConsistencyLocked(); } // Autolock scope // Wait without lock held @@ -713,10 +737,11 @@ void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { return; } + mCore->mFreeBuffers.push_front(slot); mSlots[slot].mBufferState = BufferSlot::FREE; - mSlots[slot].mFrameNumber = 0; mSlots[slot].mFence = fence; mCore->mDequeueCondition.broadcast(); + mCore->validateConsistencyLocked(); } int BufferQueueProducer::query(int what, int *outValue) { @@ -736,25 +761,28 @@ int BufferQueueProducer::query(int what, int *outValue) { int value; switch (what) { case NATIVE_WINDOW_WIDTH: - value = mCore->mDefaultWidth; + value = static_cast<int32_t>(mCore->mDefaultWidth); break; case NATIVE_WINDOW_HEIGHT: - value = mCore->mDefaultHeight; + value = static_cast<int32_t>(mCore->mDefaultHeight); break; case NATIVE_WINDOW_FORMAT: - value = mCore->mDefaultBufferFormat; + value = static_cast<int32_t>(mCore->mDefaultBufferFormat); break; case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: value = mCore->getMinUndequeuedBufferCountLocked(false); break; case NATIVE_WINDOW_STICKY_TRANSFORM: - value = static_cast<int>(mStickyTransform); + value = static_cast<int32_t>(mStickyTransform); break; case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: value = (mCore->mQueue.size() > 1); break; case NATIVE_WINDOW_CONSUMER_USAGE_BITS: - value = mCore->mConsumerUsageBits; + value = static_cast<int32_t>(mCore->mConsumerUsageBits); + break; + case NATIVE_WINDOW_DEFAULT_DATASPACE: + value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace); break; default: return BAD_VALUE; @@ -802,13 +830,14 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, case NATIVE_WINDOW_API_CAMERA: mCore->mConnectedApi = api; output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, - mCore->mTransformHint, mCore->mQueue.size()); + mCore->mTransformHint, + static_cast<uint32_t>(mCore->mQueue.size())); // Set up a death notification so that we can disconnect // automatically if the remote producer dies if (listener != NULL && - listener->asBinder()->remoteBinder() != NULL) { - status = listener->asBinder()->linkToDeath( + IInterface::asBinder(listener)->remoteBinder() != NULL) { + status = IInterface::asBinder(listener)->linkToDeath( static_cast<IBinder::DeathRecipient*>(this)); if (status != NO_ERROR) { BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", @@ -857,7 +886,7 @@ status_t BufferQueueProducer::disconnect(int api) { // Remove our death notification callback if we have one if (mCore->mConnectedProducerListener != NULL) { sp<IBinder> token = - mCore->mConnectedProducerListener->asBinder(); + IInterface::asBinder(mCore->mConnectedProducerListener); // This can fail if we're here because of the death // notification, but we just ignore it token->unlinkToDeath( @@ -904,19 +933,25 @@ status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) } void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, - uint32_t height, uint32_t format, uint32_t usage) { + uint32_t height, PixelFormat format, uint32_t usage) { ATRACE_CALL(); while (true) { Vector<int> freeSlots; size_t newBufferCount = 0; uint32_t allocWidth = 0; uint32_t allocHeight = 0; - uint32_t allocFormat = 0; + PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; uint32_t allocUsage = 0; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); + if (!mCore->mAllowAllocation) { + BQ_LOGE("allocateBuffers: allocation is not allowed for this " + "BufferQueue"); + return; + } + int currentBufferCount = 0; for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { if (mSlots[slot].mGraphicBuffer != NULL) { @@ -937,7 +972,8 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, currentBufferCount, maxBufferCount); if (maxBufferCount <= currentBufferCount) return; - newBufferCount = maxBufferCount - currentBufferCount; + newBufferCount = + static_cast<size_t>(maxBufferCount - currentBufferCount); if (freeSlots.size() < newBufferCount) { BQ_LOGE("allocateBuffers: ran out of free slots"); return; @@ -950,7 +986,7 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, mCore->mIsAllocating = true; } // Autolock scope - Vector<sp<GraphicBuffer> > buffers; + Vector<sp<GraphicBuffer>> buffers; for (size_t i = 0; i < newBufferCount; ++i) { status_t result = NO_ERROR; sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( @@ -970,7 +1006,8 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, Mutex::Autolock lock(mCore->mMutex); uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; - uint32_t checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat; + PixelFormat checkFormat = format != 0 ? + format : mCore->mDefaultBufferFormat; uint32_t checkUsage = usage | mCore->mConsumerUsageBits; if (checkWidth != allocWidth || checkHeight != allocHeight || checkFormat != allocFormat || checkUsage != allocUsage) { @@ -992,17 +1029,32 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, } mCore->freeBufferLocked(slot); // Clean up the slot first mSlots[slot].mGraphicBuffer = buffers[i]; - mSlots[slot].mFrameNumber = 0; mSlots[slot].mFence = Fence::NO_FENCE; + + // freeBufferLocked puts this slot on the free slots list. Since + // we then attached a buffer, move the slot to free buffer list. + mCore->mFreeSlots.erase(slot); + mCore->mFreeBuffers.push_front(slot); + BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); } mCore->mIsAllocating = false; mCore->mIsAllocatingCondition.broadcast(); + mCore->validateConsistencyLocked(); } // Autolock scope } } +status_t BufferQueueProducer::allowAllocation(bool allow) { + ATRACE_CALL(); + BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); + + Mutex::Autolock lock(mCore->mMutex); + mCore->mAllowAllocation = allow; + return NO_ERROR; +} + void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { // If we're here, it means that a producer we were connected to died. // We're guaranteed that we are still connected to it because we remove diff --git a/libs/gui/BufferSlot.cpp b/libs/gui/BufferSlot.cpp index b8877fe..01595de 100644 --- a/libs/gui/BufferSlot.cpp +++ b/libs/gui/BufferSlot.cpp @@ -24,8 +24,8 @@ const char* BufferSlot::bufferStateName(BufferState state) { case BufferSlot::QUEUED: return "QUEUED"; case BufferSlot::FREE: return "FREE"; case BufferSlot::ACQUIRED: return "ACQUIRED"; - default: return "Unknown"; } + return "Unknown"; } } // namespace android diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 210e98e..e576018 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -27,6 +27,7 @@ #include <hardware/hardware.h> +#include <gui/BufferItem.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> @@ -39,11 +40,11 @@ #include <utils/Trace.h> // Macros for including the ConsumerBase name in log messages -#define CB_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CB_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CB_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CB_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CB_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) +#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define CB_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define CB_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) +#define CB_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) namespace android { @@ -162,6 +163,21 @@ void ConsumerBase::setFrameAvailableListener( mFrameAvailableListener = listener; } +status_t ConsumerBase::detachBuffer(int slot) { + CB_LOGV("detachBuffer"); + Mutex::Autolock lock(mMutex); + + status_t result = mConsumer->detachBuffer(slot); + if (result != NO_ERROR) { + CB_LOGE("Failed to detach buffer: %d", result); + return result; + } + + freeBufferLocked(slot); + + return result; +} + void ConsumerBase::dump(String8& result) const { dump(result, ""); } @@ -179,7 +195,7 @@ void ConsumerBase::dumpLocked(String8& result, const char* prefix) const { } } -status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item, +status_t ConsumerBase::acquireBufferLocked(BufferItem *item, nsecs_t presentWhen) { status_t err = mConsumer->acquireBuffer(item, presentWhen); if (err != NO_ERROR) { diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp index c541ff4..eb39469 100644 --- a/libs/gui/CpuConsumer.cpp +++ b/libs/gui/CpuConsumer.cpp @@ -16,22 +16,23 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "CpuConsumer" -#define ATRACE_TAG ATRACE_TAG_GRAPHICS +//#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <cutils/compiler.h> #include <utils/Log.h> +#include <gui/BufferItem.h> #include <gui/CpuConsumer.h> -#define CC_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CC_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CC_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CC_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) -#define CC_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) +#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) +#define CC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) +#define CC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) namespace android { CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq, - uint32_t maxLockedBuffers, bool controlledByApp) : + size_t maxLockedBuffers, bool controlledByApp) : ConsumerBase(bq, controlledByApp), mMaxLockedBuffers(maxLockedBuffers), mCurrentLockedBuffers(0) @@ -40,7 +41,7 @@ CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq, mAcquiredBuffers.insertAt(0, maxLockedBuffers); mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN); - mConsumer->setMaxAcquiredBufferCount(maxLockedBuffers); + mConsumer->setMaxAcquiredBufferCount(static_cast<int32_t>(maxLockedBuffers)); } CpuConsumer::~CpuConsumer() { @@ -61,24 +62,29 @@ status_t CpuConsumer::setDefaultBufferSize(uint32_t width, uint32_t height) return mConsumer->setDefaultBufferSize(width, height); } -status_t CpuConsumer::setDefaultBufferFormat(uint32_t defaultFormat) +status_t CpuConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { Mutex::Autolock _l(mMutex); return mConsumer->setDefaultBufferFormat(defaultFormat); } +status_t CpuConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) +{ + Mutex::Autolock _l(mMutex); + return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); +} + static bool isPossiblyYUV(PixelFormat format) { - switch ((int)format) { + switch (static_cast<int>(format)) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: - case HAL_PIXEL_FORMAT_sRGB_X_8888: case HAL_PIXEL_FORMAT_Y8: case HAL_PIXEL_FORMAT_Y16: - case HAL_PIXEL_FORMAT_RAW16: // same as HAL_PIXEL_FORMAT_RAW_SENSOR + case HAL_PIXEL_FORMAT_RAW16: case HAL_PIXEL_FORMAT_RAW10: case HAL_PIXEL_FORMAT_RAW_OPAQUE: case HAL_PIXEL_FORMAT_BLOB: @@ -100,12 +106,12 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { if (!nativeBuffer) return BAD_VALUE; if (mCurrentLockedBuffers == mMaxLockedBuffers) { - CC_LOGW("Max buffers have been locked (%d), cannot lock anymore.", + CC_LOGW("Max buffers have been locked (%zd), cannot lock anymore.", mMaxLockedBuffers); return NOT_ENOUGH_DATA; } - BufferQueue::BufferItem b; + BufferItem b; Mutex::Autolock _l(mMutex); @@ -173,7 +179,7 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { } size_t lockedIdx = 0; - for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) { + for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) { if (mAcquiredBuffers[lockedIdx].mSlot == BufferQueue::INVALID_BUFFER_SLOT) { break; @@ -193,19 +199,20 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { nativeBuffer->format = format; nativeBuffer->flexFormat = flexFormat; nativeBuffer->stride = (ycbcr.y != NULL) ? - ycbcr.ystride : + static_cast<uint32_t>(ycbcr.ystride) : mSlots[buf].mGraphicBuffer->getStride(); nativeBuffer->crop = b.mCrop; nativeBuffer->transform = b.mTransform; nativeBuffer->scalingMode = b.mScalingMode; nativeBuffer->timestamp = b.mTimestamp; + nativeBuffer->dataSpace = b.mDataSpace; nativeBuffer->frameNumber = b.mFrameNumber; nativeBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); nativeBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); - nativeBuffer->chromaStride = ycbcr.cstride; - nativeBuffer->chromaStep = ycbcr.chroma_step; + nativeBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride); + nativeBuffer->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); mCurrentLockedBuffers++; @@ -215,10 +222,9 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) { Mutex::Autolock _l(mMutex); size_t lockedIdx = 0; - status_t err; void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data); - for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) { + for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) { if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break; } if (lockedIdx == mMaxLockedBuffers) { @@ -229,13 +235,13 @@ status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) { return releaseAcquiredBufferLocked(lockedIdx); } -status_t CpuConsumer::releaseAcquiredBufferLocked(int lockedIdx) { +status_t CpuConsumer::releaseAcquiredBufferLocked(size_t lockedIdx) { status_t err; int fd = -1; err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlockAsync(&fd); if (err != OK) { - CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__, + CC_LOGE("%s: Unable to unlock graphic buffer %zd", __FUNCTION__, lockedIdx); return err; } diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 318c087..96c0841 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -29,6 +29,7 @@ #include <hardware/hardware.h> +#include <gui/BufferItem.h> #include <gui/GLConsumer.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceComposer.h> @@ -47,18 +48,28 @@ EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint na namespace android { // Macros for including the GLConsumer name in log messages -#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) -#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) -#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) -#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) -#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) +#define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) +#define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) +//#define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) +#define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) +#define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) static const struct { - size_t width, height; + uint32_t width, height; char const* bits; } kDebugData = { 15, 12, - "___________________________________XX_XX_______X_X_____X_X____X_XXXXXXX_X____XXXXXXXXXXX__" - "___XX_XXX_XX_______XXXXXXX_________X___X_________X_____X__________________________________" + "_______________" + "_______________" + "_____XX_XX_____" + "__X_X_____X_X__" + "__X_XXXXXXX_X__" + "__XXXXXXXXXXX__" + "___XX_XXX_XX___" + "____XXXXXXX____" + "_____X___X_____" + "____X_____X____" + "_______________" + "_______________" }; // Transform matrices @@ -135,7 +146,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(true) { - ST_LOGV("GLConsumer"); + GLC_LOGV("GLConsumer"); memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix)); @@ -154,7 +165,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget, mDefaultWidth(1), mDefaultHeight(1), mFilteringEnabled(true), - mTexName(-1), + mTexName(0), mUseFenceSync(useFenceSync), mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), @@ -162,7 +173,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget, mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(false) { - ST_LOGV("GLConsumer"); + GLC_LOGV("GLConsumer"); memcpy(mCurrentTransformMatrix, mtxIdentity, sizeof(mCurrentTransformMatrix)); @@ -186,11 +197,11 @@ status_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) status_t GLConsumer::updateTexImage() { ATRACE_CALL(); - ST_LOGV("updateTexImage"); + GLC_LOGV("updateTexImage"); Mutex::Autolock lock(mMutex); if (mAbandoned) { - ST_LOGE("updateTexImage: GLConsumer is abandoned!"); + GLC_LOGE("updateTexImage: GLConsumer is abandoned!"); return NO_INIT; } @@ -200,7 +211,7 @@ status_t GLConsumer::updateTexImage() { return err; } - BufferQueue::BufferItem item; + BufferItem item; // Acquire the next buffer. // In asynchronous mode the list is guaranteed to be one buffer @@ -209,11 +220,11 @@ status_t GLConsumer::updateTexImage() { if (err != NO_ERROR) { if (err == BufferQueue::NO_BUFFER_AVAILABLE) { // We always bind the texture even if we don't update its contents. - ST_LOGV("updateTexImage: no buffers were available"); + GLC_LOGV("updateTexImage: no buffers were available"); glBindTexture(mTexTarget, mTexName); err = NO_ERROR; } else { - ST_LOGE("updateTexImage: acquire failed: %s (%d)", + GLC_LOGE("updateTexImage: acquire failed: %s (%d)", strerror(-err), err); } return err; @@ -234,11 +245,11 @@ status_t GLConsumer::updateTexImage() { status_t GLConsumer::releaseTexImage() { ATRACE_CALL(); - ST_LOGV("releaseTexImage"); + GLC_LOGV("releaseTexImage"); Mutex::Autolock lock(mMutex); if (mAbandoned) { - ST_LOGE("releaseTexImage: GLConsumer is abandoned!"); + GLC_LOGE("releaseTexImage: GLConsumer is abandoned!"); return NO_INIT; } @@ -258,13 +269,13 @@ status_t GLConsumer::releaseTexImage() { int buf = mCurrentTexture; if (buf != BufferQueue::INVALID_BUFFER_SLOT) { - ST_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached); + GLC_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached); if (mAttached) { // Do whatever sync ops we need to do before releasing the slot. err = syncForReleaseLocked(mEglDisplay); if (err != NO_ERROR) { - ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); + GLC_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); return err; } } else { @@ -274,7 +285,7 @@ status_t GLConsumer::releaseTexImage() { err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR); if (err < NO_ERROR) { - ST_LOGE("releaseTexImage: failed to release buffer: %s (%d)", + GLC_LOGE("releaseTexImage: failed to release buffer: %s (%d)", strerror(-err), err); return err; } @@ -293,9 +304,9 @@ status_t GLConsumer::releaseTexImage() { if (mAttached) { // This binds a dummy buffer (mReleasedTexImage). - status_t err = bindTextureImageLocked(); - if (err != NO_ERROR) { - return err; + status_t result = bindTextureImageLocked(); + if (result != NO_ERROR) { + return result; } } else { // detached, don't touch the texture (and we may not even have an @@ -316,14 +327,15 @@ sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { GraphicBuffer::USAGE_SW_WRITE_RARELY); uint32_t* bits; buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits)); - size_t w = buffer->getStride(); - size_t h = buffer->getHeight(); - memset(bits, 0, w*h*4); - for (size_t y=0 ; y<kDebugData.height ; y++) { - for (size_t x=0 ; x<kDebugData.width ; x++) { - bits[x] = (kDebugData.bits[y*kDebugData.width+x] == 'X') ? 0xFF000000 : 0xFFFFFFFF; + uint32_t stride = buffer->getStride(); + uint32_t height = buffer->getHeight(); + memset(bits, 0, stride * height * 4); + for (uint32_t y = 0; y < kDebugData.height; y++) { + for (uint32_t x = 0; x < kDebugData.width; x++) { + bits[x] = (kDebugData.bits[y + kDebugData.width + x] == 'X') ? + 0xFF000000 : 0xFFFFFFFF; } - bits += w; + bits += stride; } buffer->unlock(); sReleasedTexImageBuffer = buffer; @@ -331,7 +343,7 @@ sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { return sReleasedTexImageBuffer; } -status_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item, +status_t GLConsumer::acquireBufferLocked(BufferItem *item, nsecs_t presentWhen) { status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen); if (err != NO_ERROR) { @@ -362,14 +374,14 @@ status_t GLConsumer::releaseBufferLocked(int buf, return err; } -status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) +status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item) { status_t err = NO_ERROR; int buf = item.mBuf; if (!mAttached) { - ST_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL " + GLC_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL " "ES context"); releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR); @@ -391,7 +403,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) // means the buffer was previously acquired). err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop); if (err != NO_ERROR) { - ST_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", + GLC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", mEglDisplay, buf); releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR); @@ -410,7 +422,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) return err; } - ST_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", + GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, mCurrentTextureImage != NULL ? mCurrentTextureImage->graphicBufferHandle() : 0, buf, mSlots[buf].mGraphicBuffer->handle); @@ -421,7 +433,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) mCurrentTexture, mCurrentTextureImage->graphicBuffer(), mEglDisplay, mEglSlots[mCurrentTexture].mEglFence); if (status < NO_ERROR) { - ST_LOGE("updateAndRelease: failed to release buffer: %s (%d)", + GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); err = status; // keep going, with error raised [?] @@ -449,22 +461,22 @@ status_t GLConsumer::bindTextureImageLocked() { return INVALID_OPERATION; } - GLint error; + GLenum error; while ((error = glGetError()) != GL_NO_ERROR) { - ST_LOGW("bindTextureImage: clearing GL error: %#04x", error); + GLC_LOGW("bindTextureImage: clearing GL error: %#04x", error); } glBindTexture(mTexTarget, mTexName); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == NULL) { - ST_LOGE("bindTextureImage: no currently-bound texture"); + GLC_LOGE("bindTextureImage: no currently-bound texture"); return NO_INIT; } status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay, mCurrentCrop); if (err != NO_ERROR) { - ST_LOGW("bindTextureImage: can't create image on display=%p slot=%d", + GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", mEglDisplay, mCurrentTexture); return UNKNOWN_ERROR; } @@ -476,17 +488,17 @@ status_t GLConsumer::bindTextureImageLocked() { // forcing the creation of a new image. if ((error = glGetError()) != GL_NO_ERROR) { glBindTexture(mTexTarget, mTexName); - status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay, - mCurrentCrop, - true); - if (err != NO_ERROR) { - ST_LOGW("bindTextureImage: can't create image on display=%p slot=%d", + status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay, + mCurrentCrop, + true); + if (result != NO_ERROR) { + GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", mEglDisplay, mCurrentTexture); return UNKNOWN_ERROR; } mCurrentTextureImage->bindToTextureTarget(mTexTarget); if ((error = glGetError()) != GL_NO_ERROR) { - ST_LOGE("bindTextureImage: error binding external image: %#04x", error); + GLC_LOGE("bindTextureImage: error binding external image: %#04x", error); return UNKNOWN_ERROR; } } @@ -511,12 +523,12 @@ status_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) { } if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) { - ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); + GLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); return INVALID_OPERATION; } if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) { - ST_LOGE("checkAndUpdateEglState: invalid current EGLContext"); + GLC_LOGE("checkAndUpdateEglState: invalid current EGLContext"); return INVALID_OPERATION; } @@ -531,7 +543,7 @@ void GLConsumer::setReleaseFence(const sp<Fence>& fence) { status_t err = addReleaseFence(mCurrentTexture, mCurrentTextureImage->graphicBuffer(), fence); if (err != OK) { - ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)", + GLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err); } } @@ -539,16 +551,16 @@ void GLConsumer::setReleaseFence(const sp<Fence>& fence) { status_t GLConsumer::detachFromContext() { ATRACE_CALL(); - ST_LOGV("detachFromContext"); + GLC_LOGV("detachFromContext"); Mutex::Autolock lock(mMutex); if (mAbandoned) { - ST_LOGE("detachFromContext: abandoned GLConsumer"); + GLC_LOGE("detachFromContext: abandoned GLConsumer"); return NO_INIT; } if (!mAttached) { - ST_LOGE("detachFromContext: GLConsumer is not attached to a " + GLC_LOGE("detachFromContext: GLConsumer is not attached to a " "context"); return INVALID_OPERATION; } @@ -557,12 +569,12 @@ status_t GLConsumer::detachFromContext() { EGLContext ctx = eglGetCurrentContext(); if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { - ST_LOGE("detachFromContext: invalid current EGLDisplay"); + GLC_LOGE("detachFromContext: invalid current EGLDisplay"); return INVALID_OPERATION; } if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { - ST_LOGE("detachFromContext: invalid current EGLContext"); + GLC_LOGE("detachFromContext: invalid current EGLContext"); return INVALID_OPERATION; } @@ -584,16 +596,16 @@ status_t GLConsumer::detachFromContext() { status_t GLConsumer::attachToContext(uint32_t tex) { ATRACE_CALL(); - ST_LOGV("attachToContext"); + GLC_LOGV("attachToContext"); Mutex::Autolock lock(mMutex); if (mAbandoned) { - ST_LOGE("attachToContext: abandoned GLConsumer"); + GLC_LOGE("attachToContext: abandoned GLConsumer"); return NO_INIT; } if (mAttached) { - ST_LOGE("attachToContext: GLConsumer is already attached to a " + GLC_LOGE("attachToContext: GLConsumer is already attached to a " "context"); return INVALID_OPERATION; } @@ -602,12 +614,12 @@ status_t GLConsumer::attachToContext(uint32_t tex) { EGLContext ctx = eglGetCurrentContext(); if (dpy == EGL_NO_DISPLAY) { - ST_LOGE("attachToContext: invalid current EGLDisplay"); + GLC_LOGE("attachToContext: invalid current EGLDisplay"); return INVALID_OPERATION; } if (ctx == EGL_NO_CONTEXT) { - ST_LOGE("attachToContext: invalid current EGLContext"); + GLC_LOGE("attachToContext: invalid current EGLContext"); return INVALID_OPERATION; } @@ -636,14 +648,14 @@ status_t GLConsumer::attachToContext(uint32_t tex) { status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { - ST_LOGV("syncForReleaseLocked"); + GLC_LOGV("syncForReleaseLocked"); if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (SyncFeatures::getInstance().useNativeFenceSync()) { EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync == EGL_NO_SYNC_KHR) { - ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", + GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", eglGetError()); return UNKNOWN_ERROR; } @@ -651,7 +663,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); eglDestroySyncKHR(dpy, sync); if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { - ST_LOGE("syncForReleaseLocked: error dup'ing native fence " + GLC_LOGE("syncForReleaseLocked: error dup'ing native fence " "fd: %#x", eglGetError()); return UNKNOWN_ERROR; } @@ -659,7 +671,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { status_t err = addReleaseFenceLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer(), fence); if (err != OK) { - ST_LOGE("syncForReleaseLocked: error adding release fence: " + GLC_LOGE("syncForReleaseLocked: error adding release fence: " "%s (%d)", strerror(-err), err); return err; } @@ -672,11 +684,11 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { // before the producer accesses it. EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); if (result == EGL_FALSE) { - ST_LOGE("syncForReleaseLocked: error waiting for previous " + GLC_LOGE("syncForReleaseLocked: error waiting for previous " "fence: %#x", eglGetError()); return UNKNOWN_ERROR; } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { - ST_LOGE("syncForReleaseLocked: timeout waiting for previous " + GLC_LOGE("syncForReleaseLocked: timeout waiting for previous " "fence"); return TIMED_OUT; } @@ -687,7 +699,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { // OpenGL ES context. fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); if (fence == EGL_NO_SYNC_KHR) { - ST_LOGE("syncForReleaseLocked: error creating fence: %#x", + GLC_LOGE("syncForReleaseLocked: error creating fence: %#x", eglGetError()); return UNKNOWN_ERROR; } @@ -699,7 +711,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { return OK; } -bool GLConsumer::isExternalFormat(uint32_t format) +bool GLConsumer::isExternalFormat(PixelFormat format) { switch (format) { // supported YUV formats @@ -730,14 +742,14 @@ void GLConsumer::getTransformMatrix(float mtx[16]) { void GLConsumer::setFilteringEnabled(bool enabled) { Mutex::Autolock lock(mMutex); if (mAbandoned) { - ST_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); + GLC_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); return; } bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; if (needsRecompute && mCurrentTextureImage==NULL) { - ST_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); + GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); } if (needsRecompute && mCurrentTextureImage != NULL) { @@ -746,7 +758,7 @@ void GLConsumer::setFilteringEnabled(bool enabled) { } void GLConsumer::computeCurrentTransformMatrixLocked() { - ST_LOGV("computeCurrentTransformMatrixLocked"); + GLC_LOGV("computeCurrentTransformMatrixLocked"); float xform[16]; for (int i = 0; i < 16; i++) { @@ -778,7 +790,7 @@ void GLConsumer::computeCurrentTransformMatrixLocked() { NULL : mCurrentTextureImage->graphicBuffer(); if (buf == NULL) { - ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureImage is NULL"); + GLC_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureImage is NULL"); } float mtxBeforeFlipV[16]; @@ -850,13 +862,13 @@ void GLConsumer::computeCurrentTransformMatrixLocked() { } nsecs_t GLConsumer::getTimestamp() { - ST_LOGV("getTimestamp"); + GLC_LOGV("getTimestamp"); Mutex::Autolock lock(mMutex); return mCurrentTimestamp; } -nsecs_t GLConsumer::getFrameNumber() { - ST_LOGV("getFrameNumber"); +uint64_t GLConsumer::getFrameNumber() { + GLC_LOGV("getFrameNumber"); Mutex::Autolock lock(mMutex); return mCurrentFrameNumber; } @@ -872,30 +884,33 @@ Rect GLConsumer::getCurrentCrop() const { Rect outCrop = mCurrentCrop; if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { - int32_t newWidth = mCurrentCrop.width(); - int32_t newHeight = mCurrentCrop.height(); + uint32_t newWidth = static_cast<uint32_t>(mCurrentCrop.width()); + uint32_t newHeight = static_cast<uint32_t>(mCurrentCrop.height()); if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { newWidth = newHeight * mDefaultWidth / mDefaultHeight; - ST_LOGV("too wide: newWidth = %d", newWidth); + GLC_LOGV("too wide: newWidth = %d", newWidth); } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { newHeight = newWidth * mDefaultHeight / mDefaultWidth; - ST_LOGV("too tall: newHeight = %d", newHeight); + GLC_LOGV("too tall: newHeight = %d", newHeight); } + uint32_t currentWidth = static_cast<uint32_t>(mCurrentCrop.width()); + uint32_t currentHeight = static_cast<uint32_t>(mCurrentCrop.height()); + // The crop is too wide - if (newWidth < mCurrentCrop.width()) { - int32_t dw = (newWidth - mCurrentCrop.width())/2; - outCrop.left -=dw; - outCrop.right += dw; + if (newWidth < currentWidth) { + uint32_t dw = (currentWidth - newWidth) / 2; + outCrop.left += dw; + outCrop.right -= dw; // The crop is too tall - } else if (newHeight < mCurrentCrop.height()) { - int32_t dh = (newHeight - mCurrentCrop.height())/2; - outCrop.top -= dh; - outCrop.bottom += dh; + } else if (newHeight < currentHeight) { + uint32_t dh = (currentHeight - newHeight) / 2; + outCrop.top += dh; + outCrop.bottom -= dh; } - ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", + GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", outCrop.left, outCrop.top, outCrop.right,outCrop.bottom); } @@ -929,12 +944,12 @@ status_t GLConsumer::doGLFenceWaitLocked() const { EGLContext ctx = eglGetCurrentContext(); if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { - ST_LOGE("doGLFenceWait: invalid current EGLDisplay"); + GLC_LOGE("doGLFenceWait: invalid current EGLDisplay"); return INVALID_OPERATION; } if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { - ST_LOGE("doGLFenceWait: invalid current EGLContext"); + GLC_LOGE("doGLFenceWait: invalid current EGLContext"); return INVALID_OPERATION; } @@ -943,7 +958,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { // Create an EGLSyncKHR from the current fence. int fenceFd = mCurrentFence->dup(); if (fenceFd == -1) { - ST_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); + GLC_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); return -errno; } EGLint attribs[] = { @@ -954,7 +969,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); if (sync == EGL_NO_SYNC_KHR) { close(fenceFd); - ST_LOGE("doGLFenceWait: error creating EGL fence: %#x", + GLC_LOGE("doGLFenceWait: error creating EGL fence: %#x", eglGetError()); return UNKNOWN_ERROR; } @@ -966,7 +981,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { EGLint eglErr = eglGetError(); eglDestroySyncKHR(dpy, sync); if (eglErr != EGL_SUCCESS) { - ST_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", + GLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", eglErr); return UNKNOWN_ERROR; } @@ -974,7 +989,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { status_t err = mCurrentFence->waitForever( "GLConsumer::doGLFenceWaitLocked"); if (err != NO_ERROR) { - ST_LOGE("doGLFenceWait: error waiting for fence: %d", err); + GLC_LOGE("doGLFenceWait: error waiting for fence: %d", err); return err; } } @@ -984,7 +999,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { } void GLConsumer::freeBufferLocked(int slotIndex) { - ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); + GLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); if (slotIndex == mCurrentTexture) { mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; } @@ -993,7 +1008,7 @@ void GLConsumer::freeBufferLocked(int slotIndex) { } void GLConsumer::abandonLocked() { - ST_LOGV("abandonLocked"); + GLC_LOGV("abandonLocked"); mCurrentTextureImage.clear(); ConsumerBase::abandonLocked(); } @@ -1004,11 +1019,17 @@ void GLConsumer::setName(const String8& name) { mConsumer->setConsumerName(name); } -status_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { +status_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { Mutex::Autolock lock(mMutex); return mConsumer->setDefaultBufferFormat(defaultFormat); } +status_t GLConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + Mutex::Autolock lock(mMutex); + return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); +} + status_t GLConsumer::setConsumerUsageBits(uint32_t usage) { Mutex::Autolock lock(mMutex); usage |= DEFAULT_USAGE_FLAGS; @@ -1107,12 +1128,14 @@ status_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, } void GLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) { - glEGLImageTargetTexture2DOES(texTarget, (GLeglImageOES)mEglImage); + glEGLImageTargetTexture2DOES(texTarget, + static_cast<GLeglImageOES>(mEglImage)); } EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy, const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) { - EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); + EGLClientBuffer cbuf = + static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer()); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_IMAGE_CROP_LEFT_ANDROID, crop.left, diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp index b360e81..9643402 100644 --- a/libs/gui/GraphicBufferAlloc.cpp +++ b/libs/gui/GraphicBufferAlloc.cpp @@ -31,9 +31,10 @@ GraphicBufferAlloc::GraphicBufferAlloc() { GraphicBufferAlloc::~GraphicBufferAlloc() { } -sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage, status_t* error) { - sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); +sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width, + uint32_t height, PixelFormat format, uint32_t usage, status_t* error) { + sp<GraphicBuffer> graphicBuffer( + new GraphicBuffer(width, height, format, usage)); status_t err = graphicBuffer->initCheck(); *error = err; if (err != 0 || graphicBuffer->handle == 0) { @@ -42,7 +43,7 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h } ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " "failed (%s), handle=%p", - w, h, strerror(-err), graphicBuffer->handle); + width, height, strerror(-err), graphicBuffer->handle); return 0; } return graphicBuffer; diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp index 409dfe4..cab7dc3 100644 --- a/libs/gui/IConsumerListener.cpp +++ b/libs/gui/IConsumerListener.cpp @@ -40,6 +40,8 @@ public: : BpInterface<IConsumerListener>(impl) { } + virtual ~BpConsumerListener(); + virtual void onFrameAvailable(const BufferItem& item) { Parcel data, reply; data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor()); @@ -60,6 +62,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpConsumerListener::~BpConsumerListener() {} + IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener"); // ---------------------------------------------------------------------- diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp index 887d176..9890f44 100644 --- a/libs/gui/IDisplayEventConnection.cpp +++ b/libs/gui/IDisplayEventConnection.cpp @@ -44,6 +44,8 @@ public: { } + virtual ~BpDisplayEventConnection(); + virtual sp<BitTube> getDataChannel() const { Parcel data, reply; @@ -55,7 +57,7 @@ public: virtual void setVsyncRate(uint32_t count) { Parcel data, reply; data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor()); - data.writeInt32(count); + data.writeUint32(count); remote()->transact(SET_VSYNC_RATE, data, &reply); } @@ -66,6 +68,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpDisplayEventConnection::~BpDisplayEventConnection() {} + IMPLEMENT_META_INTERFACE(DisplayEventConnection, "android.gui.DisplayEventConnection"); // ---------------------------------------------------------------------------- @@ -79,17 +85,17 @@ status_t BnDisplayEventConnection::onTransact( sp<BitTube> channel(getDataChannel()); channel->writeToParcel(reply); return NO_ERROR; - } break; + } case SET_VSYNC_RATE: { CHECK_INTERFACE(IDisplayEventConnection, data, reply); - setVsyncRate(data.readInt32()); + setVsyncRate(data.readUint32()); return NO_ERROR; - } break; + } case REQUEST_NEXT_VSYNC: { CHECK_INTERFACE(IDisplayEventConnection, data, reply); requestNextVsync(); return NO_ERROR; - } break; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp index 139f219..09b63a1 100644 --- a/libs/gui/IGraphicBufferAlloc.cpp +++ b/libs/gui/IGraphicBufferAlloc.cpp @@ -42,14 +42,17 @@ public: { } - virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage, status_t* error) { + virtual ~BpGraphicBufferAlloc(); + + virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width, + uint32_t height, PixelFormat format, uint32_t usage, + status_t* error) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor()); - data.writeInt32(w); - data.writeInt32(h); - data.writeInt32(format); - data.writeInt32(usage); + data.writeUint32(width); + data.writeUint32(height); + data.writeInt32(static_cast<int32_t>(format)); + data.writeUint32(usage); remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply); sp<GraphicBuffer> graphicBuffer; status_t result = reply.readInt32(); @@ -65,6 +68,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpGraphicBufferAlloc::~BpGraphicBufferAlloc() {} + IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc"); // ---------------------------------------------------------------------- @@ -74,27 +81,26 @@ status_t BnGraphicBufferAlloc::onTransact( { // codes that don't require permission check - /* BufferReference just keeps a strong reference to a - * GraphicBuffer until it is destroyed (that is, until - * no local or remote process have a reference to it). - */ + // BufferReference just keeps a strong reference to a GraphicBuffer until it + // is destroyed (that is, until no local or remote process have a reference + // to it). class BufferReference : public BBinder { - sp<GraphicBuffer> buffer; + sp<GraphicBuffer> mBuffer; public: - BufferReference(const sp<GraphicBuffer>& buffer) : buffer(buffer) { } + BufferReference(const sp<GraphicBuffer>& buffer) : mBuffer(buffer) {} }; - switch(code) { + switch (code) { case CREATE_GRAPHIC_BUFFER: { CHECK_INTERFACE(IGraphicBufferAlloc, data, reply); - uint32_t w = data.readInt32(); - uint32_t h = data.readInt32(); - PixelFormat format = data.readInt32(); - uint32_t usage = data.readInt32(); + uint32_t width = data.readUint32(); + uint32_t height = data.readUint32(); + PixelFormat format = static_cast<PixelFormat>(data.readInt32()); + uint32_t usage = data.readUint32(); status_t error; sp<GraphicBuffer> result = - createGraphicBuffer(w, h, format, usage, &error); + createGraphicBuffer(width, height, format, usage, &error); reply->writeInt32(error); if (result != 0) { reply->write(*result); @@ -107,7 +113,7 @@ status_t BnGraphicBufferAlloc::onTransact( reply->writeStrongBinder( new BufferReference(result) ); } return NO_ERROR; - } break; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp index dc917a8..3c0907a 100644 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ b/libs/gui/IGraphicBufferConsumer.cpp @@ -23,6 +23,7 @@ #include <binder/Parcel.h> #include <binder/IInterface.h> +#include <gui/BufferItem.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferConsumer.h> @@ -32,159 +33,6 @@ #include <system/window.h> namespace android { -// --------------------------------------------------------------------------- - -IGraphicBufferConsumer::BufferItem::BufferItem() : - mTransform(0), - mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), - mTimestamp(0), - mIsAutoTimestamp(false), - mFrameNumber(0), - mBuf(INVALID_BUFFER_SLOT), - mIsDroppable(false), - mAcquireCalled(false), - mTransformToDisplayInverse(false) { - mCrop.makeInvalid(); -} - -size_t IGraphicBufferConsumer::BufferItem::getPodSize() const { - size_t c = sizeof(mCrop) + - sizeof(mTransform) + - sizeof(mScalingMode) + - sizeof(mTimestamp) + - sizeof(mIsAutoTimestamp) + - sizeof(mFrameNumber) + - sizeof(mBuf) + - sizeof(mIsDroppable) + - sizeof(mAcquireCalled) + - sizeof(mTransformToDisplayInverse); - return c; -} - -size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const { - size_t c = 0; - if (mGraphicBuffer != 0) { - c += mGraphicBuffer->getFlattenedSize(); - c = FlattenableUtils::align<4>(c); - } - if (mFence != 0) { - c += mFence->getFlattenedSize(); - c = FlattenableUtils::align<4>(c); - } - return sizeof(int32_t) + c + getPodSize(); -} - -size_t IGraphicBufferConsumer::BufferItem::getFdCount() const { - size_t c = 0; - if (mGraphicBuffer != 0) { - c += mGraphicBuffer->getFdCount(); - } - if (mFence != 0) { - c += mFence->getFdCount(); - } - return c; -} - -static void writeBoolAsInt(void*& buffer, size_t& size, bool b) { - FlattenableUtils::write(buffer, size, static_cast<int32_t>(b)); -} - -static bool readBoolFromInt(void const*& buffer, size_t& size) { - int32_t i; - FlattenableUtils::read(buffer, size, i); - return static_cast<bool>(i); -} - -status_t IGraphicBufferConsumer::BufferItem::flatten( - void*& buffer, size_t& size, int*& fds, size_t& count) const { - - // make sure we have enough space - if (size < BufferItem::getFlattenedSize()) { - return NO_MEMORY; - } - - // content flags are stored first - uint32_t& flags = *static_cast<uint32_t*>(buffer); - - // advance the pointer - FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); - - flags = 0; - if (mGraphicBuffer != 0) { - status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); - if (err) return err; - size -= FlattenableUtils::align<4>(buffer); - flags |= 1; - } - if (mFence != 0) { - status_t err = mFence->flatten(buffer, size, fds, count); - if (err) return err; - size -= FlattenableUtils::align<4>(buffer); - flags |= 2; - } - - // check we have enough space (in case flattening the fence/graphicbuffer lied to us) - if (size < getPodSize()) { - return NO_MEMORY; - } - - FlattenableUtils::write(buffer, size, mCrop); - FlattenableUtils::write(buffer, size, mTransform); - FlattenableUtils::write(buffer, size, mScalingMode); - FlattenableUtils::write(buffer, size, mTimestamp); - writeBoolAsInt(buffer, size, mIsAutoTimestamp); - FlattenableUtils::write(buffer, size, mFrameNumber); - FlattenableUtils::write(buffer, size, mBuf); - writeBoolAsInt(buffer, size, mIsDroppable); - writeBoolAsInt(buffer, size, mAcquireCalled); - writeBoolAsInt(buffer, size, mTransformToDisplayInverse); - - return NO_ERROR; -} - -status_t IGraphicBufferConsumer::BufferItem::unflatten( - void const*& buffer, size_t& size, int const*& fds, size_t& count) { - - if (size < sizeof(uint32_t)) - return NO_MEMORY; - - uint32_t flags = 0; - FlattenableUtils::read(buffer, size, flags); - - if (flags & 1) { - mGraphicBuffer = new GraphicBuffer(); - status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count); - if (err) return err; - size -= FlattenableUtils::align<4>(buffer); - } - - if (flags & 2) { - mFence = new Fence(); - status_t err = mFence->unflatten(buffer, size, fds, count); - if (err) return err; - size -= FlattenableUtils::align<4>(buffer); - } - - // check we have enough space - if (size < getPodSize()) { - return NO_MEMORY; - } - - FlattenableUtils::read(buffer, size, mCrop); - FlattenableUtils::read(buffer, size, mTransform); - FlattenableUtils::read(buffer, size, mScalingMode); - FlattenableUtils::read(buffer, size, mTimestamp); - mIsAutoTimestamp = readBoolFromInt(buffer, size); - FlattenableUtils::read(buffer, size, mFrameNumber); - FlattenableUtils::read(buffer, size, mBuf); - mIsDroppable = readBoolFromInt(buffer, size); - mAcquireCalled = readBoolFromInt(buffer, size); - mTransformToDisplayInverse = readBoolFromInt(buffer, size); - - return NO_ERROR; -} - -// --------------------------------------------------------------------------- enum { ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION, @@ -200,6 +48,7 @@ enum { SET_MAX_ACQUIRED_BUFFER_COUNT, SET_CONSUMER_NAME, SET_DEFAULT_BUFFER_FORMAT, + SET_DEFAULT_BUFFER_DATA_SPACE, SET_CONSUMER_USAGE_BITS, SET_TRANSFORM_HINT, GET_SIDEBAND_STREAM, @@ -215,6 +64,8 @@ public: { } + virtual ~BpGraphicBufferConsumer(); + virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); @@ -261,7 +112,7 @@ public: Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); data.writeInt32(buf); - data.writeInt64(frameNumber); + data.writeInt64(static_cast<int64_t>(frameNumber)); data.write(*releaseFence); status_t result = remote()->transact(RELEASE_BUFFER, data, &reply); if (result != NO_ERROR) { @@ -273,7 +124,7 @@ public: virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); - data.writeStrongBinder(consumer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(consumer)); data.writeInt32(controlledByApp); status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply); if (result != NO_ERROR) { @@ -303,15 +154,15 @@ public: if (result != NO_ERROR) { return result; } - *slotMask = reply.readInt64(); + *slotMask = static_cast<uint64_t>(reply.readInt64()); return reply.readInt32(); } - virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) { + virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); - data.writeInt32(w); - data.writeInt32(h); + data.writeUint32(width); + data.writeUint32(height); status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); if (result != NO_ERROR) { return result; @@ -358,10 +209,10 @@ public: remote()->transact(SET_CONSUMER_NAME, data, &reply); } - virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) { + virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); - data.writeInt32(defaultFormat); + data.writeInt32(static_cast<int32_t>(defaultFormat)); status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); if (result != NO_ERROR) { return result; @@ -369,10 +220,23 @@ public: return reply.readInt32(); } + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); + data.writeInt32(static_cast<int32_t>(defaultDataSpace)); + status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE, + data, &reply); + if (result != NO_ERROR) { + return result; + } + return reply.readInt32(); + } + virtual status_t setConsumerUsageBits(uint32_t usage) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); - data.writeInt32(usage); + data.writeUint32(usage); status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); if (result != NO_ERROR) { return result; @@ -383,7 +247,7 @@ public: virtual status_t setTransformHint(uint32_t hint) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); - data.writeInt32(hint); + data.writeUint32(hint); status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); if (result != NO_ERROR) { return result; @@ -415,6 +279,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {} + IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); // ---------------------------------------------------------------------- @@ -432,14 +300,14 @@ status_t BnGraphicBufferConsumer::onTransact( if (err) return err; reply->writeInt32(result); return NO_ERROR; - } break; + } case DETACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); int slot = data.readInt32(); int result = detachBuffer(slot); reply->writeInt32(result); return NO_ERROR; - } break; + } case ATTACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); sp<GraphicBuffer> buffer = new GraphicBuffer(); @@ -449,11 +317,11 @@ status_t BnGraphicBufferConsumer::onTransact( reply->writeInt32(slot); reply->writeInt32(result); return NO_ERROR; - } break; + } case RELEASE_BUFFER: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); int buf = data.readInt32(); - uint64_t frameNumber = data.readInt64(); + uint64_t frameNumber = static_cast<uint64_t>(data.readInt64()); sp<Fence> releaseFence = new Fence(); status_t err = data.read(*releaseFence); if (err) return err; @@ -461,7 +329,7 @@ status_t BnGraphicBufferConsumer::onTransact( EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); reply->writeInt32(result); return NO_ERROR; - } break; + } case CONSUMER_CONNECT: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); @@ -469,75 +337,83 @@ status_t BnGraphicBufferConsumer::onTransact( status_t result = consumerConnect(consumer, controlledByApp); reply->writeInt32(result); return NO_ERROR; - } break; + } case CONSUMER_DISCONNECT: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); status_t result = consumerDisconnect(); reply->writeInt32(result); return NO_ERROR; - } break; + } case GET_RELEASED_BUFFERS: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); uint64_t slotMask; status_t result = getReleasedBuffers(&slotMask); - reply->writeInt64(slotMask); + reply->writeInt64(static_cast<int64_t>(slotMask)); reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_DEFAULT_BUFFER_SIZE: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint32_t w = data.readInt32(); - uint32_t h = data.readInt32(); - status_t result = setDefaultBufferSize(w, h); + uint32_t width = data.readUint32(); + uint32_t height = data.readUint32(); + status_t result = setDefaultBufferSize(width, height); reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_DEFAULT_MAX_BUFFER_COUNT: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint32_t bufferCount = data.readInt32(); + int bufferCount = data.readInt32(); status_t result = setDefaultMaxBufferCount(bufferCount); reply->writeInt32(result); return NO_ERROR; - } break; + } case DISABLE_ASYNC_BUFFER: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); status_t result = disableAsyncBuffer(); reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_MAX_ACQUIRED_BUFFER_COUNT: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint32_t maxAcquiredBuffers = data.readInt32(); + int maxAcquiredBuffers = data.readInt32(); status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_CONSUMER_NAME: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); setConsumerName( data.readString8() ); return NO_ERROR; - } break; + } case SET_DEFAULT_BUFFER_FORMAT: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint32_t defaultFormat = data.readInt32(); + PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32()); status_t result = setDefaultBufferFormat(defaultFormat); reply->writeInt32(result); return NO_ERROR; - } break; + } + case SET_DEFAULT_BUFFER_DATA_SPACE: { + CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); + android_dataspace defaultDataSpace = + static_cast<android_dataspace>(data.readInt32()); + status_t result = setDefaultBufferDataSpace(defaultDataSpace); + reply->writeInt32(result); + return NO_ERROR; + } case SET_CONSUMER_USAGE_BITS: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint32_t usage = data.readInt32(); + uint32_t usage = data.readUint32(); status_t result = setConsumerUsageBits(usage); reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_TRANSFORM_HINT: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint32_t hint = data.readInt32(); + uint32_t hint = data.readUint32(); status_t result = setTransformHint(hint); reply->writeInt32(result); return NO_ERROR; - } break; + } case DUMP: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); String8 result = data.readString8(); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 67690b7..ec05f60 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -46,6 +46,7 @@ enum { DISCONNECT, SET_SIDEBAND_STREAM, ALLOCATE_BUFFERS, + ALLOW_ALLOCATION, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> @@ -56,6 +57,8 @@ public: { } + virtual ~BpGraphicBufferProducer(); + virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); @@ -91,14 +94,15 @@ public: } virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { + uint32_t width, uint32_t height, PixelFormat format, + uint32_t usage) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); - data.writeInt32(async); - data.writeInt32(w); - data.writeInt32(h); - data.writeInt32(format); - data.writeInt32(usage); + data.writeInt32(static_cast<int32_t>(async)); + data.writeUint32(width); + data.writeUint32(height); + data.writeInt32(static_cast<int32_t>(format)); + data.writeUint32(usage); status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply); if (result != NO_ERROR) { return result; @@ -211,7 +215,7 @@ public: data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); if (listener != NULL) { data.writeInt32(1); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); } else { data.writeInt32(0); } @@ -255,21 +259,37 @@ public: } virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, - uint32_t format, uint32_t usage) { + PixelFormat format, uint32_t usage) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeInt32(static_cast<int32_t>(async)); - data.writeInt32(static_cast<int32_t>(width)); - data.writeInt32(static_cast<int32_t>(height)); + data.writeUint32(width); + data.writeUint32(height); data.writeInt32(static_cast<int32_t>(format)); - data.writeInt32(static_cast<int32_t>(usage)); + data.writeUint32(usage); status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply); if (result != NO_ERROR) { ALOGE("allocateBuffers failed to transact: %d", result); } } + + virtual status_t allowAllocation(bool allow) { + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); + data.writeInt32(static_cast<int32_t>(allow)); + status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt32(); + return result; + } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpGraphicBufferProducer::~BpGraphicBufferProducer() {} + IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer"); // ---------------------------------------------------------------------- @@ -289,24 +309,25 @@ status_t BnGraphicBufferProducer::onTransact( } reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_BUFFER_COUNT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int bufferCount = data.readInt32(); int result = setBufferCount(bufferCount); reply->writeInt32(result); return NO_ERROR; - } break; + } case DEQUEUE_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); - bool async = data.readInt32(); - uint32_t w = data.readInt32(); - uint32_t h = data.readInt32(); - uint32_t format = data.readInt32(); - uint32_t usage = data.readInt32(); + bool async = static_cast<bool>(data.readInt32()); + uint32_t width = data.readUint32(); + uint32_t height = data.readUint32(); + PixelFormat format = static_cast<PixelFormat>(data.readInt32()); + uint32_t usage = data.readUint32(); int buf = 0; sp<Fence> fence; - int result = dequeueBuffer(&buf, &fence, async, w, h, format, usage); + int result = dequeueBuffer(&buf, &fence, async, width, height, + format, usage); reply->writeInt32(buf); reply->writeInt32(fence != NULL); if (fence != NULL) { @@ -314,14 +335,14 @@ status_t BnGraphicBufferProducer::onTransact( } reply->writeInt32(result); return NO_ERROR; - } break; + } case DETACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int slot = data.readInt32(); int result = detachBuffer(slot); reply->writeInt32(result); return NO_ERROR; - } break; + } case DETACH_NEXT_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<GraphicBuffer> buffer; @@ -339,7 +360,7 @@ status_t BnGraphicBufferProducer::onTransact( } } return NO_ERROR; - } break; + } case ATTACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<GraphicBuffer> buffer = new GraphicBuffer(); @@ -349,7 +370,7 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(slot); reply->writeInt32(result); return NO_ERROR; - } break; + } case QUEUE_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int buf = data.readInt32(); @@ -361,7 +382,7 @@ status_t BnGraphicBufferProducer::onTransact( status_t result = queueBuffer(buf, input, output); reply->writeInt32(result); return NO_ERROR; - } break; + } case CANCEL_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int buf = data.readInt32(); @@ -369,7 +390,7 @@ status_t BnGraphicBufferProducer::onTransact( data.read(*fence.get()); cancelBuffer(buf, fence); return NO_ERROR; - } break; + } case QUERY: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int value = 0; @@ -378,7 +399,7 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(value); reply->writeInt32(res); return NO_ERROR; - } break; + } case CONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<IProducerListener> listener; @@ -393,14 +414,14 @@ status_t BnGraphicBufferProducer::onTransact( status_t res = connect(listener, api, producerControlledByApp, output); reply->writeInt32(res); return NO_ERROR; - } break; + } case DISCONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int api = data.readInt32(); status_t res = disconnect(api); reply->writeInt32(res); return NO_ERROR; - } break; + } case SET_SIDEBAND_STREAM: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<NativeHandle> stream; @@ -410,16 +431,24 @@ status_t BnGraphicBufferProducer::onTransact( status_t result = setSidebandStream(stream); reply->writeInt32(result); return NO_ERROR; - } break; - case ALLOCATE_BUFFERS: + } + case ALLOCATE_BUFFERS: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); bool async = static_cast<bool>(data.readInt32()); - uint32_t width = static_cast<uint32_t>(data.readInt32()); - uint32_t height = static_cast<uint32_t>(data.readInt32()); - uint32_t format = static_cast<uint32_t>(data.readInt32()); - uint32_t usage = static_cast<uint32_t>(data.readInt32()); + uint32_t width = data.readUint32(); + uint32_t height = data.readUint32(); + PixelFormat format = static_cast<PixelFormat>(data.readInt32()); + uint32_t usage = data.readUint32(); allocateBuffers(async, width, height, format, usage); return NO_ERROR; + } + case ALLOW_ALLOCATION: { + CHECK_INTERFACE(IGraphicBufferProducer, data, reply); + bool allow = static_cast<bool>(data.readInt32()); + status_t result = allowAllocation(allow); + reply->writeInt32(result); + return NO_ERROR; + } } return BBinder::onTransact(code, data, reply, flags); } @@ -433,12 +462,14 @@ IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { return sizeof(timestamp) + sizeof(isAutoTimestamp) + + sizeof(dataSpace) + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) + sizeof(stickyTransform) + sizeof(async) - + fence->getFlattenedSize(); + + fence->getFlattenedSize() + + surfaceDamage.getFlattenedSize(); } size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { @@ -453,12 +484,17 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten( } 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, async); - return fence->flatten(buffer, size, fds, count); + status_t result = fence->flatten(buffer, size, fds, count); + if (result != NO_ERROR) { + return result; + } + return surfaceDamage.flatten(buffer, size); } status_t IGraphicBufferProducer::QueueBufferInput::unflatten( @@ -467,6 +503,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( size_t minNeeded = sizeof(timestamp) + sizeof(isAutoTimestamp) + + sizeof(dataSpace) + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) @@ -479,6 +516,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( 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); @@ -486,7 +524,11 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( FlattenableUtils::read(buffer, size, async); fence = new Fence(); - return fence->unflatten(buffer, size, fds, count); + status_t result = fence->unflatten(buffer, size, fds, count); + if (result != NO_ERROR) { + return result; + } + return surfaceDamage.unflatten(buffer, size); } }; // namespace android diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp index efe4069..81adc95 100644 --- a/libs/gui/IProducerListener.cpp +++ b/libs/gui/IProducerListener.cpp @@ -30,6 +30,8 @@ public: BpProducerListener(const sp<IBinder>& impl) : BpInterface<IProducerListener>(impl) {} + virtual ~BpProducerListener(); + virtual void onBufferReleased() { Parcel data, reply; data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); @@ -37,6 +39,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpProducerListener::~BpProducerListener() {} + IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener") status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp index 28fcb53..dc7a35c 100644 --- a/libs/gui/ISensorEventConnection.cpp +++ b/libs/gui/ISensorEventConnection.cpp @@ -45,6 +45,8 @@ public: { } + virtual ~BpSensorEventConnection(); + virtual sp<BitTube> getSensorChannel() const { Parcel data, reply; @@ -85,6 +87,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpSensorEventConnection::~BpSensorEventConnection() {} + IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection"); // ---------------------------------------------------------------------------- @@ -98,7 +104,7 @@ status_t BnSensorEventConnection::onTransact( sp<BitTube> channel(getSensorChannel()); channel->writeToParcel(reply); return NO_ERROR; - } break; + } case ENABLE_DISABLE: { CHECK_INTERFACE(ISensorEventConnection, data, reply); int handle = data.readInt32(); @@ -110,21 +116,21 @@ status_t BnSensorEventConnection::onTransact( maxBatchReportLatencyNs, reservedFlags); reply->writeInt32(result); return NO_ERROR; - } break; + } case SET_EVENT_RATE: { CHECK_INTERFACE(ISensorEventConnection, data, reply); int handle = data.readInt32(); - int ns = data.readInt64(); + nsecs_t ns = data.readInt64(); status_t result = setEventRate(handle, ns); reply->writeInt32(result); return NO_ERROR; - } break; + } case FLUSH_SENSOR: { CHECK_INTERFACE(ISensorEventConnection, data, reply); status_t result = flush(); reply->writeInt32(result); return NO_ERROR; - } break; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp index 0b76f37..8e09e7c 100644 --- a/libs/gui/ISensorServer.cpp +++ b/libs/gui/ISensorServer.cpp @@ -45,6 +45,8 @@ public: { } + virtual ~BpSensorServer(); + virtual Vector<Sensor> getSensorList() { Parcel data, reply; @@ -52,7 +54,7 @@ public: remote()->transact(GET_SENSOR_LIST, data, &reply); Sensor s; Vector<Sensor> v; - int32_t n = reply.readInt32(); + uint32_t n = reply.readUint32(); v.setCapacity(n); while (n--) { reply.read(s); @@ -70,6 +72,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpSensorServer::~BpSensorServer() {} + IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer"); // ---------------------------------------------------------------------- @@ -82,18 +88,18 @@ status_t BnSensorServer::onTransact( CHECK_INTERFACE(ISensorServer, data, reply); Vector<Sensor> v(getSensorList()); size_t n = v.size(); - reply->writeInt32(n); - for (size_t i=0 ; i<n ; i++) { + reply->writeUint32(static_cast<uint32_t>(n)); + for (size_t i = 0; i < n; i++) { reply->write(v[i]); } return NO_ERROR; - } break; + } case CREATE_SENSOR_EVENT_CONNECTION: { CHECK_INTERFACE(ISensorServer, data, reply); sp<ISensorEventConnection> connection(createSensorEventConnection()); - reply->writeStrongBinder(connection->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(connection)); return NO_ERROR; - } break; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index ebb687a..78886d5 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -51,9 +51,10 @@ public: { } + virtual ~BpSurfaceComposer(); + virtual sp<ISurfaceComposerClient> createConnection() { - uint32_t n; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply); @@ -62,7 +63,6 @@ public: virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() { - uint32_t n; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply); @@ -76,23 +76,18 @@ public: { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - { - Vector<ComposerState>::const_iterator b(state.begin()); - Vector<ComposerState>::const_iterator e(state.end()); - data.writeInt32(state.size()); - for ( ; b != e ; ++b ) { - b->write(data); - } + + data.writeUint32(static_cast<uint32_t>(state.size())); + for (const auto& s : state) { + s.write(data); } - { - Vector<DisplayState>::const_iterator b(displays.begin()); - Vector<DisplayState>::const_iterator e(displays.end()); - data.writeInt32(displays.size()); - for ( ; b != e ; ++b ) { - b->write(data); - } + + data.writeUint32(static_cast<uint32_t>(displays.size())); + for (const auto& d : displays) { + d.write(data); } - data.writeInt32(flags); + + data.writeUint32(flags); remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } @@ -113,12 +108,12 @@ public: Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); - data.writeStrongBinder(producer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(producer)); data.write(sourceCrop); - data.writeInt32(reqWidth); - data.writeInt32(reqHeight); - data.writeInt32(minLayerZ); - data.writeInt32(maxLayerZ); + data.writeUint32(reqWidth); + data.writeUint32(reqHeight); + data.writeUint32(minLayerZ); + data.writeUint32(maxLayerZ); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(rotation)); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); @@ -137,7 +132,7 @@ public: "interface descriptor: %s (%d)", strerror(-err), -err); return false; } - err = data.writeStrongBinder(bufferProducer->asBinder()); + err = data.writeStrongBinder(IInterface::asBinder(bufferProducer)); if (err != NO_ERROR) { ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing " "strong binder to parcel: %s (%d)", strerror(-err), -err); @@ -226,7 +221,7 @@ public: remote()->transact(BnSurfaceComposer::GET_DISPLAY_CONFIGS, data, &reply); status_t result = reply.readInt32(); if (result == NO_ERROR) { - size_t numConfigs = static_cast<size_t>(reply.readInt32()); + size_t numConfigs = reply.readUint32(); configs->clear(); configs->resize(numConfigs); for (size_t c = 0; c < numConfigs; ++c) { @@ -289,6 +284,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpSurfaceComposer::~BpSurfaceComposer() {} + IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer"); // ---------------------------------------------------------------------- @@ -299,46 +298,49 @@ status_t BnSurfaceComposer::onTransact( switch(code) { case CREATE_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - sp<IBinder> b = createConnection()->asBinder(); + sp<IBinder> b = IInterface::asBinder(createConnection()); reply->writeStrongBinder(b); return NO_ERROR; } case CREATE_GRAPHIC_BUFFER_ALLOC: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - sp<IBinder> b = createGraphicBufferAlloc()->asBinder(); + sp<IBinder> b = IInterface::asBinder(createGraphicBufferAlloc()); reply->writeStrongBinder(b); return NO_ERROR; } case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - size_t count = data.readInt32(); + + size_t count = data.readUint32(); if (count > data.dataSize()) { return BAD_VALUE; } ComposerState s; Vector<ComposerState> state; state.setCapacity(count); - for (size_t i=0 ; i<count ; i++) { + for (size_t i = 0; i < count; i++) { if (s.read(data) == BAD_VALUE) { return BAD_VALUE; } state.add(s); } - count = data.readInt32(); + + count = data.readUint32(); if (count > data.dataSize()) { return BAD_VALUE; } DisplayState d; Vector<DisplayState> displays; displays.setCapacity(count); - for (size_t i=0 ; i<count ; i++) { + for (size_t i = 0; i < count; i++) { if (d.read(data) == BAD_VALUE) { return BAD_VALUE; } displays.add(d); } - uint32_t flags = data.readInt32(); - setTransactionState(state, displays, flags); + + uint32_t stateFlags = data.readUint32(); + setTransactionState(state, displays, stateFlags); return NO_ERROR; } case BOOT_FINISHED: { @@ -353,12 +355,12 @@ status_t BnSurfaceComposer::onTransact( interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); Rect sourceCrop; data.read(sourceCrop); - uint32_t reqWidth = data.readInt32(); - uint32_t reqHeight = data.readInt32(); - uint32_t minLayerZ = data.readInt32(); - uint32_t maxLayerZ = data.readInt32(); + uint32_t reqWidth = data.readUint32(); + uint32_t reqHeight = data.readUint32(); + uint32_t minLayerZ = data.readUint32(); + uint32_t maxLayerZ = data.readUint32(); bool useIdentityTransform = static_cast<bool>(data.readInt32()); - uint32_t rotation = data.readInt32(); + int32_t rotation = data.readInt32(); status_t res = captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, @@ -378,7 +380,7 @@ status_t BnSurfaceComposer::onTransact( case CREATE_DISPLAY_EVENT_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IDisplayEventConnection> connection(createDisplayEventConnection()); - reply->writeStrongBinder(connection->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(connection)); return NO_ERROR; } case CREATE_DISPLAY: { @@ -409,7 +411,7 @@ status_t BnSurfaceComposer::onTransact( status_t result = getDisplayConfigs(display, &configs); reply->writeInt32(result); if (result == NO_ERROR) { - reply->writeInt32(static_cast<int32_t>(configs.size())); + reply->writeUint32(static_cast<uint32_t>(configs.size())); for (size_t c = 0; c < configs.size(); ++c) { memcpy(reply->writeInplace(sizeof(DisplayInfo)), &configs[c], sizeof(DisplayInfo)); @@ -469,8 +471,6 @@ status_t BnSurfaceComposer::onTransact( return BBinder::onTransact(code, data, reply, flags); } } - // should be unreachable - return NO_ERROR; } // ---------------------------------------------------------------------------- diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp index 3da6423..2ecb908 100644 --- a/libs/gui/ISurfaceComposerClient.cpp +++ b/libs/gui/ISurfaceComposerClient.cpp @@ -51,17 +51,19 @@ public: : BpInterface<ISurfaceComposerClient>(impl) { } - virtual status_t createSurface(const String8& name, uint32_t w, - uint32_t h, PixelFormat format, uint32_t flags, + virtual ~BpSurfaceComposerClient(); + + virtual status_t createSurface(const String8& name, uint32_t width, + uint32_t height, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); data.writeString8(name); - data.writeInt32(w); - data.writeInt32(h); - data.writeInt32(format); - data.writeInt32(flags); + data.writeUint32(width); + data.writeUint32(height); + data.writeInt32(static_cast<int32_t>(format)); + data.writeUint32(flags); remote()->transact(CREATE_SURFACE, data, &reply); *handle = reply.readStrongBinder(); *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder()); @@ -94,6 +96,10 @@ public: } }; +// Out-of-line virtual method definition to trigger vtable emission in this +// translation unit (see clang warning -Wweak-vtables) +BpSurfaceComposerClient::~BpSurfaceComposerClient() {} + IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient"); // ---------------------------------------------------------------------- @@ -105,31 +111,31 @@ status_t BnSurfaceComposerClient::onTransact( case CREATE_SURFACE: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); String8 name = data.readString8(); - uint32_t w = data.readInt32(); - uint32_t h = data.readInt32(); - PixelFormat format = data.readInt32(); - uint32_t flags = data.readInt32(); + uint32_t width = data.readUint32(); + uint32_t height = data.readUint32(); + PixelFormat format = static_cast<PixelFormat>(data.readInt32()); + uint32_t createFlags = data.readUint32(); sp<IBinder> handle; sp<IGraphicBufferProducer> gbp; - status_t result = createSurface(name, w, h, format, flags, - &handle, &gbp); + status_t result = createSurface(name, width, height, format, + createFlags, &handle, &gbp); reply->writeStrongBinder(handle); - reply->writeStrongBinder(gbp->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(gbp)); reply->writeInt32(result); return NO_ERROR; - } break; + } case DESTROY_SURFACE: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); reply->writeInt32(destroySurface( data.readStrongBinder() ) ); return NO_ERROR; - } break; + } case CLEAR_LAYER_FRAME_STATS: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); sp<IBinder> handle = data.readStrongBinder(); status_t result = clearLayerFrameStats(handle); reply->writeInt32(result); return NO_ERROR; - } break; + } case GET_LAYER_FRAME_STATS: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); sp<IBinder> handle = data.readStrongBinder(); @@ -138,7 +144,7 @@ status_t BnSurfaceComposerClient::onTransact( reply->write(stats); reply->writeInt32(result); return NO_ERROR; - } break; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 1183d59..00323dc 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -25,16 +25,16 @@ namespace android { status_t layer_state_t::write(Parcel& output) const { output.writeStrongBinder(surface); - output.writeInt32(what); + output.writeUint32(what); output.writeFloat(x); output.writeFloat(y); - output.writeInt32(z); - output.writeInt32(w); - output.writeInt32(h); - output.writeInt32(layerStack); + output.writeUint32(z); + output.writeUint32(w); + output.writeUint32(h); + output.writeUint32(layerStack); output.writeFloat(alpha); - output.writeInt32(flags); - output.writeInt32(mask); + output.writeUint32(flags); + output.writeUint32(mask); *reinterpret_cast<layer_state_t::matrix22_t *>( output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix; output.write(crop); @@ -45,16 +45,16 @@ status_t layer_state_t::write(Parcel& output) const status_t layer_state_t::read(const Parcel& input) { surface = input.readStrongBinder(); - what = input.readInt32(); + what = input.readUint32(); x = input.readFloat(); y = input.readFloat(); - z = input.readInt32(); - w = input.readInt32(); - h = input.readInt32(); - layerStack = input.readInt32(); + z = input.readUint32(); + w = input.readUint32(); + h = input.readUint32(); + layerStack = input.readUint32(); alpha = input.readFloat(); - flags = input.readInt32(); - mask = input.readInt32(); + flags = static_cast<uint8_t>(input.readUint32()); + mask = static_cast<uint8_t>(input.readUint32()); const void* matrix_data = input.readInplace(sizeof(layer_state_t::matrix22_t)); if (matrix_data) { matrix = *reinterpret_cast<layer_state_t::matrix22_t const *>(matrix_data); @@ -67,7 +67,7 @@ status_t layer_state_t::read(const Parcel& input) } status_t ComposerState::write(Parcel& output) const { - output.writeStrongBinder(client->asBinder()); + output.writeStrongBinder(IInterface::asBinder(client)); return state.write(output); } @@ -79,27 +79,27 @@ status_t ComposerState::read(const Parcel& input) { status_t DisplayState::write(Parcel& output) const { output.writeStrongBinder(token); - output.writeStrongBinder(surface->asBinder()); - output.writeInt32(what); - output.writeInt32(layerStack); - output.writeInt32(orientation); + output.writeStrongBinder(IInterface::asBinder(surface)); + output.writeUint32(what); + output.writeUint32(layerStack); + output.writeUint32(orientation); output.write(viewport); output.write(frame); - output.writeInt32(width); - output.writeInt32(height); + output.writeUint32(width); + output.writeUint32(height); return NO_ERROR; } status_t DisplayState::read(const Parcel& input) { token = input.readStrongBinder(); surface = interface_cast<IGraphicBufferProducer>(input.readStrongBinder()); - what = input.readInt32(); - layerStack = input.readInt32(); - orientation = input.readInt32(); + what = input.readUint32(); + layerStack = input.readUint32(); + orientation = input.readUint32(); input.read(viewport); input.read(frame); - width = input.readInt32(); - height = input.readInt32(); + width = input.readUint32(); + height = input.readUint32(); return NO_ERROR; } diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp index b4291bb..35661f2 100644 --- a/libs/gui/Sensor.cpp +++ b/libs/gui/Sensor.cpp @@ -72,7 +72,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) static_cast<int64_t>(hwSensor->maxDelay)); mMaxDelay = INT_MAX; } else { - mMaxDelay = (int32_t) hwSensor->maxDelay; + mMaxDelay = static_cast<int32_t>(hwSensor->maxDelay); } } else { // For older hals set maxDelay to 0. @@ -204,6 +204,13 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) mFlags |= SENSOR_FLAG_WAKE_UP; } break; + case SENSOR_TYPE_WRIST_TILT_GESTURE: + mStringType = SENSOR_STRING_TYPE_WRIST_TILT_GESTURE; + mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE; + if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) { + mFlags |= SENSOR_FLAG_WAKE_UP; + } + break; default: // Only pipe the stringType, requiredPermission and flags for custom sensors. if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) { @@ -214,7 +221,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) } if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) { - mFlags = (int32_t) hwSensor->flags; + mFlags = static_cast<uint32_t>(hwSensor->flags); } else { // This is an OEM defined sensor on an older HAL. Use minDelay to determine the // reporting mode of the sensor. @@ -295,11 +302,11 @@ int32_t Sensor::getVersion() const { return mVersion; } -int32_t Sensor::getFifoReservedEventCount() const { +uint32_t Sensor::getFifoReservedEventCount() const { return mFifoReservedEventCount; } -int32_t Sensor::getFifoMaxEventCount() const { +uint32_t Sensor::getFifoMaxEventCount() const { return mFifoMaxEventCount; } @@ -315,7 +322,7 @@ int32_t Sensor::getMaxDelay() const { return mMaxDelay; } -int32_t Sensor::getFlags() const { +uint32_t Sensor::getFlags() const { return mFlags; } @@ -407,7 +414,7 @@ status_t Sensor::unflatten(void const* buffer, size_t size) { void Sensor::flattenString8(void*& buffer, size_t& size, const String8& string8) { - uint32_t len = string8.length(); + uint32_t len = static_cast<uint32_t>(string8.length()); FlattenableUtils::write(buffer, size, len); memcpy(static_cast<char*>(buffer), string8.string(), len); FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp index 1305e9f..76ae470 100644 --- a/libs/gui/SensorEventQueue.cpp +++ b/libs/gui/SensorEventQueue.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "Sensors" +#include <algorithm> #include <stdint.h> #include <sys/types.h> #include <sys/socket.h> @@ -31,6 +32,8 @@ #include <android/sensor.h> +using std::min; + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- @@ -68,14 +71,14 @@ ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) { if (err < 0) { return err; } - mAvailable = err; + mAvailable = static_cast<size_t>(err); mConsumed = 0; } - size_t count = numEvents < mAvailable ? numEvents : mAvailable; - memcpy(events, mRecBuffer + mConsumed, count*sizeof(ASensorEvent)); + size_t count = min(numEvents, mAvailable); + memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent)); mAvailable -= count; mConsumed += count; - return count; + return static_cast<ssize_t>(count); } sp<Looper> SensorEventQueue::getLooper() const @@ -157,7 +160,7 @@ void SensorEventQueue::sendAck(const ASensorEvent* events, int count) { ssize_t size = ::send(mSensorChannel->getFd(), &mNumAcksToSend, sizeof(mNumAcksToSend), MSG_DONTWAIT | MSG_NOSIGNAL); if (size < 0) { - ALOGE("sendAck failure %d %d", size, mNumAcksToSend); + ALOGE("sendAck failure %zd %d", size, mNumAcksToSend); } else { mNumAcksToSend = 0; } diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index 7b4fa2f..d6df404 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -86,11 +86,12 @@ status_t SensorManager::assertStateLocked() const { }; mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this)); - mSensorServer->asBinder()->linkToDeath(mDeathObserver); + IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver); mSensors = mSensorServer->getSensorList(); size_t count = mSensors.size(); - mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*)); + mSensorList = + static_cast<Sensor const**>(malloc(count * sizeof(Sensor*))); for (size_t i=0 ; i<count ; i++) { mSensorList[i] = mSensors.array() + i; } @@ -106,10 +107,10 @@ ssize_t SensorManager::getSensorList(Sensor const* const** list) const Mutex::Autolock _l(mLock); status_t err = assertStateLocked(); if (err < 0) { - return ssize_t(err); + return static_cast<ssize_t>(err); } *list = mSensorList; - return mSensors.size(); + return static_cast<ssize_t>(mSensors.size()); } Sensor const* SensorManager::getDefaultSensor(int type) diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp index 5f39905..43f9214 100644 --- a/libs/gui/StreamSplitter.cpp +++ b/libs/gui/StreamSplitter.cpp @@ -20,6 +20,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 +#include <gui/BufferItem.h> #include <gui/IGraphicBufferConsumer.h> #include <gui/IGraphicBufferProducer.h> #include <gui/StreamSplitter.h> @@ -80,7 +81,7 @@ status_t StreamSplitter::addOutput( IGraphicBufferProducer::QueueBufferOutput queueBufferOutput; sp<OutputListener> listener(new OutputListener(this, outputQueue)); - outputQueue->asBinder()->linkToDeath(listener); + IInterface::asBinder(outputQueue)->linkToDeath(listener); status_t status = outputQueue->connect(listener, NATIVE_WINDOW_API_CPU, /* producerControlledByApp */ false, &queueBufferOutput); if (status != NO_ERROR) { @@ -123,7 +124,7 @@ void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) { ++mOutstandingBuffers; // Acquire and detach the buffer from the input - IGraphicBufferConsumer::BufferItem bufferItem; + BufferItem bufferItem; status_t status = mInput->acquireBuffer(&bufferItem, /* presentWhen */ 0); LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "acquiring buffer from input failed (%d)", status); @@ -141,7 +142,8 @@ void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) { IGraphicBufferProducer::QueueBufferInput queueInput( bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp, - bufferItem.mCrop, bufferItem.mScalingMode, + bufferItem.mDataSpace, bufferItem.mCrop, + static_cast<int32_t>(bufferItem.mScalingMode), bufferItem.mTransform, bufferItem.mIsDroppable, bufferItem.mFence); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 0e2baa2..b8acad2 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -27,6 +27,7 @@ #include <utils/NativeHandle.h> #include <ui/Fence.h> +#include <ui/Region.h> #include <gui/IProducerListener.h> #include <gui/ISurfaceComposer.h> @@ -64,6 +65,7 @@ Surface::Surface( mReqFormat = 0; mReqUsage = 0; mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; + mDataSpace = HAL_DATASPACE_UNKNOWN; mCrop.clear(); mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0; @@ -96,8 +98,8 @@ void Surface::setSidebandStream(const sp<NativeHandle>& stream) { void Surface::allocateBuffers() { uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth; uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight; - mGraphicBufferProducer->allocateBuffers(mSwapIntervalZero, mReqWidth, - mReqHeight, mReqFormat, mReqUsage); + mGraphicBufferProducer->allocateBuffers(mSwapIntervalZero, reqWidth, + reqHeight, mReqFormat, mReqUsage); } int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { @@ -193,17 +195,17 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { ATRACE_CALL(); ALOGV("Surface::dequeueBuffer"); - int reqW; - int reqH; + uint32_t reqWidth; + uint32_t reqHeight; bool swapIntervalZero; - uint32_t reqFormat; + PixelFormat reqFormat; uint32_t reqUsage; { Mutex::Autolock lock(mMutex); - reqW = mReqWidth ? mReqWidth : mUserWidth; - reqH = mReqHeight ? mReqHeight : mUserHeight; + reqWidth = mReqWidth ? mReqWidth : mUserWidth; + reqHeight = mReqHeight ? mReqHeight : mUserHeight; swapIntervalZero = mSwapIntervalZero; reqFormat = mReqFormat; @@ -213,12 +215,12 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { int buf = -1; sp<Fence> fence; status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero, - reqW, reqH, reqFormat, reqUsage); + reqWidth, reqHeight, reqFormat, reqUsage); if (result < 0) { ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d, %d)" - "failed: %d", swapIntervalZero, reqW, reqH, reqFormat, reqUsage, - result); + "failed: %d", swapIntervalZero, reqWidth, reqHeight, reqFormat, + reqUsage, result); return result; } @@ -274,7 +276,6 @@ int Surface::cancelBuffer(android_native_buffer_t* buffer, int Surface::getSlotFromBufferLocked( android_native_buffer_t* buffer) const { - bool dumpedState = false; for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { if (mSlots[i].buffer != NULL && mSlots[i].buffer->handle == buffer->handle) { @@ -318,8 +319,27 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, - crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero, - fence, mStickyTransform); + mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform, + mSwapIntervalZero, fence, mStickyTransform); + + if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) { + input.setSurfaceDamage(Region::INVALID_REGION); + } else { + // The surface damage was specified using the OpenGL ES convention of + // the origin being in the bottom-left corner. Here we flip to the + // convention that the rest of the system uses (top-left corner) by + // subtracting all top/bottom coordinates from the buffer height. + Region flippedRegion; + for (auto rect : mDirtyRegion) { + auto top = buffer->height - rect.bottom; + auto bottom = buffer->height - rect.top; + Rect flippedRect{rect.left, top, rect.right, bottom}; + flippedRegion.orSelf(flippedRect); + } + + input.setSurfaceDamage(flippedRegion); + } + status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); if (err != OK) { ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); @@ -336,6 +356,11 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mConsumerRunningBehind = (numPendingBuffers >= 2); + if (!mConnectedToCpu) { + // Clear surface damage back to full-buffer + mDirtyRegion = Region::INVALID_REGION; + } + return err; } @@ -347,7 +372,7 @@ int Surface::query(int what, int* value) const { switch (what) { case NATIVE_WINDOW_FORMAT: if (mReqFormat) { - *value = mReqFormat; + *value = static_cast<int>(mReqFormat); return NO_ERROR; } break; @@ -365,13 +390,15 @@ int Surface::query(int what, int* value) const { *value = NATIVE_WINDOW_SURFACE; return NO_ERROR; case NATIVE_WINDOW_DEFAULT_WIDTH: - *value = mUserWidth ? mUserWidth : mDefaultWidth; + *value = static_cast<int>( + mUserWidth ? mUserWidth : mDefaultWidth); return NO_ERROR; case NATIVE_WINDOW_DEFAULT_HEIGHT: - *value = mUserHeight ? mUserHeight : mDefaultHeight; + *value = static_cast<int>( + mUserHeight ? mUserHeight : mDefaultHeight); return NO_ERROR; case NATIVE_WINDOW_TRANSFORM_HINT: - *value = mTransformHint; + *value = static_cast<int>(mTransformHint); return NO_ERROR; case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { status_t err = NO_ERROR; @@ -448,6 +475,12 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_SIDEBAND_STREAM: res = dispatchSetSidebandStream(args); break; + case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: + res = dispatchSetBuffersDataSpace(args); + break; + case NATIVE_WINDOW_SET_SURFACE_DAMAGE: + res = dispatchSetSurfaceDamage(args); + break; default: res = NAME_NOT_FOUND; break; @@ -467,7 +500,7 @@ int Surface::dispatchDisconnect(va_list args) { int Surface::dispatchSetUsage(va_list args) { int usage = va_arg(args, int); - return setUsage(usage); + return setUsage(static_cast<uint32_t>(usage)); } int Surface::dispatchSetCrop(va_list args) { @@ -477,49 +510,49 @@ int Surface::dispatchSetCrop(va_list args) { int Surface::dispatchSetBufferCount(va_list args) { size_t bufferCount = va_arg(args, size_t); - return setBufferCount(bufferCount); + return setBufferCount(static_cast<int32_t>(bufferCount)); } int Surface::dispatchSetBuffersGeometry(va_list args) { - int w = va_arg(args, int); - int h = va_arg(args, int); - int f = va_arg(args, int); - int err = setBuffersDimensions(w, h); + uint32_t width = va_arg(args, uint32_t); + uint32_t height = va_arg(args, uint32_t); + PixelFormat format = va_arg(args, PixelFormat); + int err = setBuffersDimensions(width, height); if (err != 0) { return err; } - return setBuffersFormat(f); + return setBuffersFormat(format); } int Surface::dispatchSetBuffersDimensions(va_list args) { - int w = va_arg(args, int); - int h = va_arg(args, int); - return setBuffersDimensions(w, h); + uint32_t width = va_arg(args, uint32_t); + uint32_t height = va_arg(args, uint32_t); + return setBuffersDimensions(width, height); } int Surface::dispatchSetBuffersUserDimensions(va_list args) { - int w = va_arg(args, int); - int h = va_arg(args, int); - return setBuffersUserDimensions(w, h); + uint32_t width = va_arg(args, uint32_t); + uint32_t height = va_arg(args, uint32_t); + return setBuffersUserDimensions(width, height); } int Surface::dispatchSetBuffersFormat(va_list args) { - int f = va_arg(args, int); - return setBuffersFormat(f); + PixelFormat format = va_arg(args, PixelFormat); + return setBuffersFormat(format); } int Surface::dispatchSetScalingMode(va_list args) { - int m = va_arg(args, int); - return setScalingMode(m); + int mode = va_arg(args, int); + return setScalingMode(mode); } int Surface::dispatchSetBuffersTransform(va_list args) { - int transform = va_arg(args, int); + uint32_t transform = va_arg(args, uint32_t); return setBuffersTransform(transform); } int Surface::dispatchSetBuffersStickyTransform(va_list args) { - int transform = va_arg(args, int); + uint32_t transform = va_arg(args, uint32_t); return setBuffersStickyTransform(transform); } @@ -545,10 +578,27 @@ int Surface::dispatchSetSidebandStream(va_list args) { return OK; } +int Surface::dispatchSetBuffersDataSpace(va_list args) { + android_dataspace dataspace = + static_cast<android_dataspace>(va_arg(args, int)); + return setBuffersDataSpace(dataspace); +} + +int Surface::dispatchSetSurfaceDamage(va_list args) { + android_native_rect_t* rects = va_arg(args, android_native_rect_t*); + size_t numRects = va_arg(args, size_t); + setSurfaceDamage(rects, numRects); + return NO_ERROR; +} + int Surface::connect(int api) { + static sp<IProducerListener> listener = new DummyProducerListener(); + return connect(api, listener); +} + +int Surface::connect(int api, const sp<IProducerListener>& listener) { ATRACE_CALL(); ALOGV("Surface::connect"); - static sp<IProducerListener> listener = new DummyProducerListener(); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); @@ -567,7 +617,13 @@ int Surface::connect(int api) { } if (!err && api == NATIVE_WINDOW_API_CPU) { mConnectedToCpu = true; + // Clear the dirty region in case we're switching from a non-CPU API + mDirtyRegion.clear(); + } else if (!err) { + // Initialize the dirty region for tracking surface damage + mDirtyRegion = Region::INVALID_REGION; } + return err; } @@ -595,6 +651,55 @@ int Surface::disconnect(int api) { return err; } +int Surface::detachNextBuffer(ANativeWindowBuffer** outBuffer, + sp<Fence>* outFence) { + ATRACE_CALL(); + ALOGV("Surface::detachNextBuffer"); + + if (outBuffer == NULL || outFence == NULL) { + return BAD_VALUE; + } + + Mutex::Autolock lock(mMutex); + + sp<GraphicBuffer> buffer(NULL); + sp<Fence> fence(NULL); + status_t result = mGraphicBufferProducer->detachNextBuffer( + &buffer, &fence); + if (result != NO_ERROR) { + return result; + } + + *outBuffer = buffer.get(); + if (fence != NULL && fence->isValid()) { + *outFence = fence; + } else { + *outFence = Fence::NO_FENCE; + } + + return NO_ERROR; +} + +int Surface::attachBuffer(ANativeWindowBuffer* buffer) +{ + ATRACE_CALL(); + ALOGV("Surface::attachBuffer"); + + Mutex::Autolock lock(mMutex); + + sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer)); + int32_t attachedSlot = -1; + status_t result = mGraphicBufferProducer->attachBuffer( + &attachedSlot, graphicBuffer); + if (result != NO_ERROR) { + ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result); + return result; + } + mSlots[attachedSlot].buffer = graphicBuffer; + + return NO_ERROR; +} + int Surface::setUsage(uint32_t reqUsage) { ALOGV("Surface::setUsage"); @@ -639,47 +744,38 @@ int Surface::setBufferCount(int bufferCount) return err; } -int Surface::setBuffersDimensions(int w, int h) +int Surface::setBuffersDimensions(uint32_t width, uint32_t height) { ATRACE_CALL(); ALOGV("Surface::setBuffersDimensions"); - if (w<0 || h<0) - return BAD_VALUE; - - if ((w && !h) || (!w && h)) + if ((width && !height) || (!width && height)) return BAD_VALUE; Mutex::Autolock lock(mMutex); - mReqWidth = w; - mReqHeight = h; + mReqWidth = width; + mReqHeight = height; return NO_ERROR; } -int Surface::setBuffersUserDimensions(int w, int h) +int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height) { ATRACE_CALL(); ALOGV("Surface::setBuffersUserDimensions"); - if (w<0 || h<0) - return BAD_VALUE; - - if ((w && !h) || (!w && h)) + if ((width && !height) || (!width && height)) return BAD_VALUE; Mutex::Autolock lock(mMutex); - mUserWidth = w; - mUserHeight = h; + mUserWidth = width; + mUserHeight = height; return NO_ERROR; } -int Surface::setBuffersFormat(int format) +int Surface::setBuffersFormat(PixelFormat format) { ALOGV("Surface::setBuffersFormat"); - if (format<0) - return BAD_VALUE; - Mutex::Autolock lock(mMutex); mReqFormat = format; return NO_ERROR; @@ -705,7 +801,7 @@ int Surface::setScalingMode(int mode) return NO_ERROR; } -int Surface::setBuffersTransform(int transform) +int Surface::setBuffersTransform(uint32_t transform) { ATRACE_CALL(); ALOGV("Surface::setBuffersTransform"); @@ -714,7 +810,7 @@ int Surface::setBuffersTransform(int transform) return NO_ERROR; } -int Surface::setBuffersStickyTransform(int transform) +int Surface::setBuffersStickyTransform(uint32_t transform) { ATRACE_CALL(); ALOGV("Surface::setBuffersStickyTransform"); @@ -731,12 +827,41 @@ int Surface::setBuffersTimestamp(int64_t timestamp) return NO_ERROR; } +int Surface::setBuffersDataSpace(android_dataspace dataSpace) +{ + ALOGV("Surface::setBuffersDataSpace"); + Mutex::Autolock lock(mMutex); + mDataSpace = dataSpace; + return NO_ERROR; +} + void Surface::freeAllBuffers() { for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { mSlots[i].buffer = 0; } } +void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { + ATRACE_CALL(); + ALOGV("Surface::setSurfaceDamage"); + Mutex::Autolock lock(mMutex); + + if (mConnectedToCpu || numRects == 0) { + mDirtyRegion = Region::INVALID_REGION; + return; + } + + mDirtyRegion.clear(); + for (size_t r = 0; r < numRects; ++r) { + // We intentionally flip top and bottom here, since because they're + // specified with a bottom-left origin, top > bottom, which fails + // validation in the Region class. We will fix this up when we flip to a + // top-left origin in queueBuffer. + Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top); + mDirtyRegion.orSelf(rect); + } +} + // ---------------------------------------------------------------------- // the lock/unlock APIs must be used from the same thread @@ -748,30 +873,34 @@ static status_t copyBlt( // src and dst with, height and format must be identical. no verification // is done here. status_t err; - uint8_t const * src_bits = NULL; - err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); + uint8_t* src_bits = NULL; + err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), + reinterpret_cast<void**>(&src_bits)); ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); uint8_t* dst_bits = NULL; - err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); + err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), + reinterpret_cast<void**>(&dst_bits)); ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); Region::const_iterator head(reg.begin()); Region::const_iterator tail(reg.end()); if (head != tail && src_bits && dst_bits) { const size_t bpp = bytesPerPixel(src->format); - const size_t dbpr = dst->stride * bpp; - const size_t sbpr = src->stride * bpp; + const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp; + const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp; while (head != tail) { const Rect& r(*head++); - ssize_t h = r.height(); + int32_t h = r.height(); if (h <= 0) continue; - size_t size = r.width() * bpp; - uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; - uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + size_t size = static_cast<uint32_t>(r.width()) * bpp; + uint8_t const * s = src_bits + + static_cast<uint32_t>(r.left + src->stride * r.top) * bpp; + uint8_t * d = dst_bits + + static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp; if (dbpr==sbpr && size==sbpr) { - size *= h; + size *= static_cast<size_t>(h); h = 1; } do { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6446926..707a321 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -71,7 +71,7 @@ void ComposerService::connectLocked() { }; mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this)); - mComposerService->asBinder()->linkToDeath(mDeathObserver); + IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver); } /*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() { @@ -143,7 +143,7 @@ public: status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, uint32_t w, uint32_t h); status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, - int32_t z); + uint32_t z); status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, uint32_t flags, uint32_t mask); status_t setTransparentRegionHint( @@ -293,7 +293,7 @@ status_t Composer::setSize(const sp<SurfaceComposerClient>& client, } status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, - const sp<IBinder>& id, int32_t z) { + const sp<IBinder>& id, uint32_t z) { Mutex::Autolock _l(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) @@ -395,7 +395,7 @@ DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) { s.what = 0; index = mDisplayStates.add(s); } - return mDisplayStates.editItemAt(index); + return mDisplayStates.editItemAt(static_cast<size_t>(index)); } void Composer::setDisplaySurface(const sp<IBinder>& token, @@ -462,14 +462,14 @@ status_t SurfaceComposerClient::initCheck() const { } sp<IBinder> SurfaceComposerClient::connection() const { - return (mClient != 0) ? mClient->asBinder() : 0; + return IInterface::asBinder(mClient); } status_t SurfaceComposerClient::linkToComposerDeath( const sp<IBinder::DeathRecipient>& recipient, void* cookie, uint32_t flags) { sp<ISurfaceComposer> sm(ComposerService::getComposerService()); - return sm->asBinder()->linkToDeath(recipient, cookie, flags); + return IInterface::asBinder(sm)->linkToDeath(recipient, cookie, flags); } void SurfaceComposerClient::dispose() { @@ -571,7 +571,7 @@ status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint3 return getComposer().setSize(this, id, w, h); } -status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { +status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, uint32_t z) { return getComposer().setLayer(this, id, z); } @@ -657,7 +657,7 @@ status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display, return NAME_NOT_FOUND; } - *info = configs[activeId]; + *info = configs[static_cast<size_t>(activeId)]; return NO_ERROR; } @@ -752,14 +752,14 @@ status_t ScreenshotClient::update(const sp<IBinder>& display, status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, bool useIdentityTransform) { - return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1UL, + return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1U, useIdentityTransform, ISurfaceComposer::eRotateNone); } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight, - 0, -1UL, useIdentityTransform, ISurfaceComposer::eRotateNone); + 0, -1U, useIdentityTransform, ISurfaceComposer::eRotateNone); } void ScreenshotClient::release() { diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 7597c99..1983027 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -89,12 +89,12 @@ bool SurfaceControl::isSameSurface( return lhs->mHandle == rhs->mHandle; } -status_t SurfaceControl::setLayerStack(int32_t layerStack) { +status_t SurfaceControl::setLayerStack(uint32_t layerStack) { status_t err = validate(); if (err < 0) return err; return mClient->setLayerStack(mHandle, layerStack); } -status_t SurfaceControl::setLayer(int32_t layer) { +status_t SurfaceControl::setLayer(uint32_t layer) { status_t err = validate(); if (err < 0) return err; return mClient->setLayer(mHandle, layer); @@ -176,7 +176,7 @@ status_t SurfaceControl::writeSurfaceToParcel( if (control != NULL) { bp = control->mGraphicBufferProducer; } - return parcel->writeStrongBinder(bp->asBinder()); + return parcel->writeStrongBinder(IInterface::asBinder(bp)); } sp<Surface> SurfaceControl::getSurface() const diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp index e5804a7..187b211 100644 --- a/libs/gui/SyncFeatures.cpp +++ b/libs/gui/SyncFeatures.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "GLConsumer" -#define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES #include <EGL/egl.h> @@ -78,10 +77,11 @@ bool SyncFeatures::useFenceSync() const { // on some devices it's better to not use EGL_KHR_fence_sync // even if they have it return false; -#endif +#else // currently we shall only attempt to use EGL_KHR_fence_sync if // USE_FENCE_SYNC is set in our makefile return !mHasNativeFenceSync && mHasFenceSync; +#endif } bool SyncFeatures::useWaitSync() const { return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync; diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk index e460290..6ad9986 100644 --- a/libs/gui/tests/Android.mk +++ b/libs/gui/tests/Android.mk @@ -1,6 +1,9 @@ # Build the unit tests, LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + +LOCAL_CLANG := true LOCAL_MODULE := libgui_test @@ -31,17 +34,10 @@ LOCAL_SHARED_LIBRARIES := \ libbinder \ libcutils \ libgui \ - libstlport \ libsync \ libui \ libutils \ -LOCAL_C_INCLUDES := \ - bionic \ - bionic/libstdc++/include \ - external/gtest/include \ - external/stlport/stlport \ - # Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) # to integrate with auto-test framework. include $(BUILD_NATIVE_TEST) diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 96de11f..1584fef 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "BufferQueue_test" //#define LOG_NDEBUG 0 +#include <gui/BufferItem.h> #include <gui/BufferQueue.h> #include <gui/IProducerListener.h> @@ -72,6 +73,8 @@ struct DummyConsumer : public BnConsumerListener { virtual void onSidebandStreamChanged() {} }; +static const uint32_t TEST_DATA = 0x12345678u; + // XXX: Tests that fork a process to hold the BufferQueue must run before tests // that use a local BufferQueue, or else Binder will get unhappy TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { @@ -87,8 +90,8 @@ TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp<IServiceManager> serviceManager = defaultServiceManager(); - serviceManager->addService(PRODUCER_NAME, producer->asBinder()); - serviceManager->addService(CONSUMER_NAME, consumer->asBinder()); + serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer)); + serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer)); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); LOG_ALWAYS_FATAL("Shouldn't be here"); @@ -121,20 +124,21 @@ TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); - *dataIn = 0x12345678; + *dataIn = TEST_DATA; ASSERT_EQ(OK, buffer->unlock()); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - IGraphicBufferConsumer::BufferItem item; + BufferItem item; ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(*dataOut, TEST_DATA); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } @@ -150,9 +154,10 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { int slot; sp<Fence> fence; sp<GraphicBuffer> buf; - IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput qbi(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); - BufferQueue::BufferItem item; + BufferItem item; for (int i = 0; i < 2; i++) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, @@ -236,7 +241,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); - *dataIn = 0x12345678; + *dataIn = TEST_DATA; ASSERT_EQ(OK, buffer->unlock()); int newSlot; @@ -244,17 +249,18 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL)); ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer)); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); - IGraphicBufferConsumer::BufferItem item; + BufferItem item; ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(*dataOut, TEST_DATA); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } @@ -273,7 +279,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); @@ -282,7 +289,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired - IGraphicBufferConsumer::BufferItem item; + BufferItem item; ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf)); @@ -292,7 +299,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { ASSERT_EQ(OK, item.mGraphicBuffer->lock( GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); - *dataIn = 0x12345678; + *dataIn = TEST_DATA; ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); int newSlot; @@ -312,7 +319,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { uint32_t* dataOut; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(*dataOut, TEST_DATA); ASSERT_EQ(OK, buffer->unlock()); } @@ -335,14 +342,15 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); - *dataIn = 0x12345678; + *dataIn = TEST_DATA; ASSERT_EQ(OK, buffer->unlock()); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - IGraphicBufferConsumer::BufferItem item; + BufferItem item; ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf)); @@ -354,8 +362,44 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(*dataOut, TEST_DATA); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } +TEST_F(BufferQueueTest, TestDisallowingAllocation) { + createBufferQueue(); + sp<DummyConsumer> dc(new DummyConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + IGraphicBufferProducer::QueueBufferOutput output; + ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, + NATIVE_WINDOW_API_CPU, true, &output)); + + static const uint32_t WIDTH = 320; + static const uint32_t HEIGHT = 240; + + ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT)); + + int slot; + sp<Fence> fence; + sp<GraphicBuffer> buffer; + // This should return an error since it would require an allocation + ASSERT_EQ(OK, mProducer->allowAllocation(false)); + ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, + 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); + + // This should succeed, now that we've lifted the prohibition + ASSERT_EQ(OK, mProducer->allowAllocation(true)); + ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, + mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, + GRALLOC_USAGE_SW_WRITE_OFTEN)); + + // Release the previous buffer back to the BufferQueue + mProducer->cancelBuffer(slot, fence); + + // This should fail since we're requesting a different size + ASSERT_EQ(OK, mProducer->allowAllocation(false)); + ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, + WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); +} + } // namespace android diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp index abd3724..2dc9ccc 100644 --- a/libs/gui/tests/CpuConsumer_test.cpp +++ b/libs/gui/tests/CpuConsumer_test.cpp @@ -94,7 +94,7 @@ protected: mPendingFrames--; } - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem&) { Mutex::Autolock lock(mMutex); mPendingFrames++; mCondition.signal(); @@ -125,7 +125,7 @@ protected: mPendingFrames--; } - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem&) { Mutex::Autolock lock(mMutex); mPendingFrames++; mFrameCondition.signal(); @@ -166,7 +166,7 @@ void checkPixel(const CpuConsumer::LockedBuffer &buf, uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) { // Ignores components that don't exist for given pixel switch(buf.format) { - case HAL_PIXEL_FORMAT_RAW_SENSOR: { + case HAL_PIXEL_FORMAT_RAW16: { String8 msg; uint16_t *bPtr = (uint16_t*)buf.data; bPtr += y * buf.stride + x; @@ -429,7 +429,7 @@ void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) { void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) { switch (format) { - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: checkBayerRawBuffer(buf); break; case HAL_PIXEL_FORMAT_Y8: @@ -457,9 +457,12 @@ void configureANW(const sp<ANativeWindow>& anw, const CpuConsumerTestParams& params, int maxBufferSlack) { status_t err; - err = native_window_set_buffers_geometry(anw.get(), - params.width, params.height, params.format); - ASSERT_NO_ERROR(err, "set_buffers_geometry error: "); + err = native_window_set_buffers_dimensions(anw.get(), + params.width, params.height); + ASSERT_NO_ERROR(err, "set_buffers_dimensions error: "); + + err = native_window_set_buffers_format(anw.get(), params.format); + ASSERT_NO_ERROR(err, "set_buffers_format error: "); err = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); @@ -505,7 +508,7 @@ void produceOneFrame(const sp<ANativeWindow>& anw, case HAL_PIXEL_FORMAT_YV12: fillYV12Buffer(img, params.width, params.height, *stride); break; - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: fillBayerRawBuffer(img, params.width, params.height, buf->getStride()); break; case HAL_PIXEL_FORMAT_Y8: @@ -537,7 +540,7 @@ void produceOneFrame(const sp<ANativeWindow>& anw, ASSERT_NO_ERROR(err, "queueBuffer error:"); }; -// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not +// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not // supported on all devices. TEST_P(CpuConsumerTest, FromCpuSingle) { status_t err; @@ -571,7 +574,7 @@ TEST_P(CpuConsumerTest, FromCpuSingle) { mCC->unlockBuffer(b); } -// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not +// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not // supported on all devices. TEST_P(CpuConsumerTest, FromCpuManyInQueue) { status_t err; @@ -614,7 +617,7 @@ TEST_P(CpuConsumerTest, FromCpuManyInQueue) { } } -// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not +// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not // supported on all devices. TEST_P(CpuConsumerTest, FromCpuLockMax) { status_t err; @@ -710,12 +713,12 @@ CpuConsumerTestParams y16TestSets[] = { }; CpuConsumerTestParams rawTestSets[] = { - { 512, 512, 1, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 512, 512, 3, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 100, 100, 1, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 100, 100, 3, HAL_PIXEL_FORMAT_RAW_SENSOR}, + { 512, 512, 1, HAL_PIXEL_FORMAT_RAW16}, + { 512, 512, 3, HAL_PIXEL_FORMAT_RAW16}, + { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16}, + { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16}, + { 100, 100, 1, HAL_PIXEL_FORMAT_RAW16}, + { 100, 100, 3, HAL_PIXEL_FORMAT_RAW16}, }; CpuConsumerTestParams rgba8888TestSets[] = { diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 8d5fd8f..ff58420 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -38,30 +38,31 @@ #define TEST_CONTROLLED_BY_APP false #define TEST_PRODUCER_USAGE_BITS (0) -// TODO: Make these public constants in a header -enum { +namespace android { + +namespace { // Default dimensions before setDefaultBufferSize is called - DEFAULT_WIDTH = 1, - DEFAULT_HEIGHT = 1, + const uint32_t DEFAULT_WIDTH = 1; + const uint32_t DEFAULT_HEIGHT = 1; // Default format before setDefaultBufferFormat is called - DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888, + const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888; // Default transform hint before setTransformHint is called - DEFAULT_TRANSFORM_HINT = 0, -}; + const uint32_t DEFAULT_TRANSFORM_HINT = 0; -namespace android { + // TODO: Make these constants in header + const int DEFAULT_CONSUMER_USAGE_BITS = 0; -namespace { -// Parameters for a generic "valid" input for queueBuffer. -const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611; -const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false; -const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT); -const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0; -const int QUEUE_BUFFER_INPUT_TRANSFORM = 0; -const bool QUEUE_BUFFER_INPUT_ASYNC = false; -const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE; + // Parameters for a generic "valid" input for queueBuffer. + const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611; + const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false; + const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN; + const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT); + const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0; + const int QUEUE_BUFFER_INPUT_TRANSFORM = 0; + const bool QUEUE_BUFFER_INPUT_ASYNC = false; + const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE; }; // namespace anonymous struct DummyConsumer : public BnConsumerListener { @@ -126,6 +127,7 @@ protected: QueueBufferInputBuilder() { timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP; isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP; + dataSpace = QUEUE_BUFFER_INPUT_DATASPACE; crop = QUEUE_BUFFER_INPUT_RECT; scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE; transform = QUEUE_BUFFER_INPUT_TRANSFORM; @@ -137,6 +139,7 @@ protected: return IGraphicBufferProducer::QueueBufferInput( timestamp, isAutoTimestamp, + dataSpace, crop, scalingMode, transform, @@ -154,6 +157,11 @@ protected: return *this; } + QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) { + this->dataSpace = dataSpace; + return *this; + } + QueueBufferInputBuilder& setCrop(Rect crop) { this->crop = crop; return *this; @@ -182,6 +190,7 @@ protected: private: int64_t timestamp; bool isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; @@ -264,15 +273,12 @@ TEST_F(IGraphicBufferProducerTest, Disconnect_ReturnsError) { TEST_F(IGraphicBufferProducerTest, Query_Succeeds) { ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - // TODO: Make these constants in header - const int DEFAULT_CONSUMER_USAGE_BITS = 0; - - int value = -1; + int32_t value = -1; EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value)); - EXPECT_EQ(DEFAULT_WIDTH, value); + EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value)); EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value)); - EXPECT_EQ(DEFAULT_HEIGHT, value); + EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value)); EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value)); EXPECT_EQ(DEFAULT_FORMAT, value); @@ -293,7 +299,7 @@ TEST_F(IGraphicBufferProducerTest, Query_ReturnsError) { ASSERT_NO_FATAL_FAILURE(ConnectProducer()); // One past the end of the last 'query' enum value. Update this if we add more enums. - const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_CONSUMER_USAGE_BITS + 1; + const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_DEFAULT_DATASPACE + 1; int value; // What was out of range @@ -360,7 +366,7 @@ TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) { EXPECT_EQ(DEFAULT_WIDTH, width); EXPECT_EQ(DEFAULT_HEIGHT, height); EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint); - EXPECT_EQ(1, numPendingBuffers); // since queueBuffer was called exactly once + EXPECT_EQ(1u, numPendingBuffers); // since queueBuffer was called exactly once } // Buffer was not in the dequeued state diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp index 2d5b8aa..3b11b97 100644 --- a/libs/gui/tests/SRGB_test.cpp +++ b/libs/gui/tests/SRGB_test.cpp @@ -17,8 +17,14 @@ #define LOG_TAG "SRGB_test" //#define LOG_NDEBUG 0 +// Ignore for this file because it flags every instance of +// ASSERT_EQ(GL_NO_ERROR, glGetError()); +#pragma clang diagnostic ignored "-Wsign-compare" + #include "GLTest.h" +#include <math.h> + #include <gui/CpuConsumer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> @@ -212,10 +218,11 @@ protected: ASSERT_EQ(GL_NO_ERROR, glGetError()); } - void checkLockedBuffer(PixelFormat format) { + void checkLockedBuffer(PixelFormat format, android_dataspace dataSpace) { ASSERT_EQ(mLockedBuffer.format, format); ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH); ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT); + ASSERT_EQ(mLockedBuffer.dataSpace, dataSpace); } static bool withinTolerance(int a, int b) { @@ -326,14 +333,15 @@ private: ANativeWindow_Buffer outBuffer; ARect outBufferBounds; mOutputSurface->lock(&outBuffer, &outBufferBounds); - ASSERT_EQ(mLockedBuffer.width, outBuffer.width); - ASSERT_EQ(mLockedBuffer.height, outBuffer.height); - ASSERT_EQ(mLockedBuffer.stride, outBuffer.stride); + ASSERT_EQ(mLockedBuffer.width, static_cast<uint32_t>(outBuffer.width)); + ASSERT_EQ(mLockedBuffer.height, static_cast<uint32_t>(outBuffer.height)); + ASSERT_EQ(mLockedBuffer.stride, static_cast<uint32_t>(outBuffer.stride)); if (mLockedBuffer.format == outBuffer.format) { memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize); } else { - ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_sRGB_A_8888); + ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_RGBA_8888); + ASSERT_EQ(mLockedBuffer.dataSpace, HAL_DATASPACE_SRGB); ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888); uint8_t* outPointer = reinterpret_cast<uint8_t*>(outBuffer.bits); for (int y = 0; y < outBuffer.height; ++y) { @@ -378,7 +386,8 @@ TEST_F(SRGBTest, GLRenderFromSRGBTexture) { // Lock ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer)); - ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888)); + ASSERT_NO_FATAL_FAILURE( + checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN)); // Compare a pixel in the middle of each texture int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride * @@ -396,7 +405,8 @@ TEST_F(SRGBTest, GLRenderFromSRGBTexture) { // the debug surface if necessary } -TEST_F(SRGBTest, RenderToSRGBSurface) { +// XXX: Disabled since we don't currently expect this to work +TEST_F(SRGBTest, DISABLED_RenderToSRGBSurface) { ASSERT_NO_FATAL_FAILURE(initShaders()); // By default, the first buffer we write into will be RGB @@ -409,7 +419,8 @@ TEST_F(SRGBTest, RenderToSRGBSurface) { // Lock ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer)); - ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888)); + ASSERT_NO_FATAL_FAILURE( + checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN)); // Save the values of the middle pixel for later comparison against SRGB uint8_t values[PIXEL_SIZE] = {}; @@ -458,7 +469,8 @@ TEST_F(SRGBTest, RenderToSRGBSurface) { ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer)); // Make sure we actually got the SRGB buffer on the consumer side - ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_sRGB_A_8888)); + ASSERT_NO_FATAL_FAILURE( + checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_SRGB)); // Verify that the stored value is the same, accounting for RGB/SRGB for (int c = 0; c < PIXEL_SIZE; ++c) { diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index 4e63a6f..00cc39d 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "StreamSplitter_test" //#define LOG_NDEBUG 0 +#include <gui/BufferItem.h> #include <gui/BufferQueue.h> #include <gui/IConsumerListener.h> #include <gui/ISurfaceComposer.h> @@ -75,6 +76,8 @@ private: int mAllocCount; }; +static const uint32_t TEST_DATA = 0x12345678u; + TEST_F(StreamSplitterTest, OneInputOneOutput) { sp<CountedAllocator> allocator(new CountedAllocator); @@ -107,21 +110,22 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); - *dataIn = 0x12345678; + *dataIn = TEST_DATA; ASSERT_EQ(OK, buffer->unlock()); IGraphicBufferProducer::QueueBufferInput qbInput(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); - IGraphicBufferConsumer::BufferItem item; + BufferItem item; ASSERT_EQ(OK, outputConsumer->acquireBuffer(&item, 0)); uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(*dataOut, TEST_DATA); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mBuf, item.mFrameNumber, @@ -173,22 +177,23 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); - *dataIn = 0x12345678; + *dataIn = TEST_DATA; ASSERT_EQ(OK, buffer->unlock()); IGraphicBufferProducer::QueueBufferInput qbInput(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); for (int output = 0; output < NUM_OUTPUTS; ++output) { - IGraphicBufferConsumer::BufferItem item; + BufferItem item; ASSERT_EQ(OK, outputConsumers[output]->acquireBuffer(&item, 0)); uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(*dataOut, TEST_DATA); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); ASSERT_EQ(OK, outputConsumers[output]->releaseBuffer(item.mBuf, @@ -234,6 +239,7 @@ TEST_F(StreamSplitterTest, OutputAbandonment) { outputConsumer->consumerDisconnect(); IGraphicBufferProducer::QueueBufferInput qbInput(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index 8cdf3bc..d750cd0 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -207,12 +207,8 @@ TEST_F(SurfaceTextureClientTest, EglSwapBuffersAbandonErrorIsEglBadSurface) { } TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) { - EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, 0, 0)); - EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, -1, 0)); - EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, -1)); - EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1, 0)); - EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 8, 0)); - EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 8, 0, 0)); + EXPECT_GT(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 8)); + EXPECT_GT(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 0)); } TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) { @@ -226,7 +222,8 @@ TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) { TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) { ANativeWindowBuffer* buf; - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf)); EXPECT_EQ(16, buf->width); EXPECT_EQ(8, buf->height); @@ -236,7 +233,8 @@ TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) { TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) { ANativeWindowBuffer* buf; - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf)); EXPECT_EQ(1, buf->width); EXPECT_EQ(1, buf->height); @@ -246,7 +244,8 @@ TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) { TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) { ANativeWindowBuffer* buf; - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf)); EXPECT_EQ(16, buf->width); EXPECT_EQ(8, buf->height); @@ -256,13 +255,15 @@ TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) { TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) { ANativeWindowBuffer* buf; - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf)); EXPECT_EQ(16, buf->width); EXPECT_EQ(8, buf->height); EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format); ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1)); - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf)); EXPECT_EQ(1, buf->width); EXPECT_EQ(1, buf->height); @@ -272,7 +273,8 @@ TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) { TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) { ANativeWindowBuffer* buf; - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf)); EXPECT_EQ(1, buf->width); EXPECT_EQ(1, buf->height); @@ -330,7 +332,8 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) { EXPECT_EQ(8, buf[1]->height); ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1)); ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1)); - EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0)); + EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 12, 24)); + EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0])); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1])); EXPECT_NE(buf[0], buf[1]); @@ -468,7 +471,8 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) { // Once we've queued a buffer, however we should not be able to dequeue more // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case. - EXPECT_EQ(-EBUSY, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1])); + EXPECT_EQ(INVALID_OPERATION, + native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1])); ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1)); ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1)); @@ -620,7 +624,8 @@ TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWi crop.bottom = 5; ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); - ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0)); + ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 8)); + ASSERT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0)); ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0])); ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop)); ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1)); @@ -668,7 +673,8 @@ TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) { const int numFmts = (sizeof(fmts) / sizeof(fmts[0])); for (int i = 0; i < numFmts; i++) { int fmt = -1; - ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i])); + ASSERT_EQ(OK, native_window_set_buffers_dimensions(anw.get(), 0, 0)); + ASSERT_EQ(OK, native_window_set_buffers_format(anw.get(), fmts[i])); ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt)); EXPECT_EQ(fmts[i], fmt); } diff --git a/libs/gui/tests/SurfaceTextureFBO_test.cpp b/libs/gui/tests/SurfaceTextureFBO_test.cpp index b165ae6..c243fc0 100644 --- a/libs/gui/tests/SurfaceTextureFBO_test.cpp +++ b/libs/gui/tests/SurfaceTextureFBO_test.cpp @@ -27,8 +27,10 @@ TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) { const int texWidth = 64; const int texHeight = 64; - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_RGBA_8888)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp index fa1e1b7..fad133f 100644 --- a/libs/gui/tests/SurfaceTextureGL_test.cpp +++ b/libs/gui/tests/SurfaceTextureGL_test.cpp @@ -28,8 +28,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) { const int texWidth = 64; const int texHeight = 66; - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); @@ -74,8 +76,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) { const int texWidth = 64; const int texHeight = 64; - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); @@ -120,8 +124,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { const int texWidth = 64; const int texHeight = 66; - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); @@ -185,8 +191,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) { enum { numFrames = 1024 }; ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2)); - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_YV12)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_WRITE_OFTEN)); @@ -326,8 +334,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) { const int texWidth = 64; const int texHeight = 66; - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_RGBA_8888)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); @@ -368,8 +378,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) { const int texWidth = 64; const int texHeight = 64; - ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), - texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), + texWidth, texHeight)); + ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), + HAL_PIXEL_FORMAT_RGBA_8888)); ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 5e6aeef..4f87824 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -155,4 +155,26 @@ TEST_F(SurfaceTest, QueryConsumerUsage) { ASSERT_EQ(TEST_USAGE_FLAGS, flags); } +TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) { + const android_dataspace TEST_DATASPACE = HAL_DATASPACE_SRGB; + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1); + + cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE); + + sp<Surface> s = new Surface(producer); + + sp<ANativeWindow> anw(s); + + android_dataspace dataSpace; + + int err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, + reinterpret_cast<int*>(&dataSpace)); + + ASSERT_EQ(NO_ERROR, err); + ASSERT_EQ(TEST_DATASPACE, dataSpace); +} + } |