| /* | |
| * Copyright (C) 2018 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. | |
| */ | |
| #pragma once | |
| #include <android-base/unique_fd.h> | |
| #include <system/window.h> | |
| #include <apex/window.h> | |
| #include <utils/Errors.h> | |
| #include <utils/Macros.h> | |
| #ifdef __ANDROID__ | |
| #include <utils/NdkUtils.h> | |
| #endif | |
| #include <utils/StrongPointer.h> | |
| #include <memory> | |
| #include <mutex> | |
| namespace android::uirenderer::renderthread { | |
| class ReliableSurface { | |
| PREVENT_COPY_AND_ASSIGN(ReliableSurface); | |
| public: | |
| ReliableSurface(ANativeWindow* window); | |
| ~ReliableSurface(); | |
| // Performs initialization that is not safe to do in the constructor. | |
| // For instance, registering ANativeWindow interceptors with ReliableSurface | |
| // passed as the data pointer is not safe. | |
| void init(); | |
| ANativeWindow* getNativeWindow() { return mWindow; } | |
| int reserveNext(); | |
| int getAndClearError() { | |
| int ret = mBufferQueueState; | |
| mBufferQueueState = OK; | |
| return ret; | |
| } | |
| bool didSetExtraBuffers() const { | |
| std::lock_guard _lock{mMutex}; | |
| return mDidSetExtraBuffers; | |
| } | |
| private: | |
| ANativeWindow* mWindow; | |
| mutable std::mutex mMutex; | |
| uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; | |
| #ifdef __ANDROID__ | |
| AHardwareBuffer_Format mFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; | |
| UniqueAHardwareBuffer mScratchBuffer; | |
| ANativeWindowBuffer* mReservedBuffer = nullptr; | |
| #endif | |
| base::unique_fd mReservedFenceFd; | |
| bool mHasDequeuedBuffer = false; | |
| int mBufferQueueState = OK; | |
| size_t mExpectedBufferCount = 0; | |
| bool mDidSetExtraBuffers = false; | |
| bool isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const; | |
| ANativeWindowBuffer* acquireFallbackBuffer(int error); | |
| void clearReservedBuffer(); | |
| // ANativeWindow hooks. When an ANativeWindow_* method is called on the | |
| // underlying ANativeWindow, these methods will intercept the original call. | |
| // For example, an EGL driver would call into these hooks instead of the | |
| // original methods. | |
| static int hook_cancelBuffer(ANativeWindow* window, ANativeWindow_cancelBufferFn cancelBuffer, | |
| void* data, ANativeWindowBuffer* buffer, int fenceFd); | |
| static int hook_dequeueBuffer(ANativeWindow* window, | |
| ANativeWindow_dequeueBufferFn dequeueBuffer, void* data, | |
| ANativeWindowBuffer** buffer, int* fenceFd); | |
| static int hook_queueBuffer(ANativeWindow* window, ANativeWindow_queueBufferFn queueBuffer, | |
| void* data, ANativeWindowBuffer* buffer, int fenceFd); | |
| static int hook_perform(ANativeWindow* window, ANativeWindow_performFn perform, void* data, | |
| int operation, va_list args); | |
| static int hook_query(const ANativeWindow* window, ANativeWindow_queryFn query, void* data, | |
| int what, int* value); | |
| }; | |
| }; // namespace android::uirenderer::renderthread |