| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2018 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #pragma once | 
|  | 18 |  | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 19 | #include <android-base/unique_fd.h> | 
| John Reck | 8ddbc59 | 2020-05-07 16:11:18 -0700 | [diff] [blame] | 20 | #include <system/window.h> | 
| Alec Mouri | f023a32 | 2019-11-25 10:02:21 -0800 | [diff] [blame] | 21 | #include <apex/window.h> | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 22 | #include <utils/Errors.h> | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 23 | #include <utils/Macros.h> | 
| Alec Mouri | 4523801 | 2020-01-29 11:04:40 -0800 | [diff] [blame] | 24 | #include <utils/NdkUtils.h> | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 25 | #include <utils/StrongPointer.h> | 
|  | 26 |  | 
|  | 27 | #include <memory> | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 28 | #include <mutex> | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 29 |  | 
|  | 30 | namespace android::uirenderer::renderthread { | 
|  | 31 |  | 
| Alec Mouri | f023a32 | 2019-11-25 10:02:21 -0800 | [diff] [blame] | 32 | class ReliableSurface { | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 33 | PREVENT_COPY_AND_ASSIGN(ReliableSurface); | 
|  | 34 |  | 
|  | 35 | public: | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 36 | ReliableSurface(ANativeWindow* window); | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 37 | ~ReliableSurface(); | 
|  | 38 |  | 
| Alec Mouri | f023a32 | 2019-11-25 10:02:21 -0800 | [diff] [blame] | 39 | // Performs initialization that is not safe to do in the constructor. | 
|  | 40 | // For instance, registering ANativeWindow interceptors with ReliableSurface | 
|  | 41 | // passed as the data pointer is not safe. | 
|  | 42 | void init(); | 
|  | 43 |  | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 44 | ANativeWindow* getNativeWindow() { return mWindow; } | 
| Alec Mouri | f023a32 | 2019-11-25 10:02:21 -0800 | [diff] [blame] | 45 |  | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 46 | int reserveNext(); | 
|  | 47 |  | 
| John Reck | 59dd2ea | 2019-07-26 16:51:08 -0700 | [diff] [blame] | 48 | int getAndClearError() { | 
|  | 49 | int ret = mBufferQueueState; | 
|  | 50 | mBufferQueueState = OK; | 
|  | 51 | return ret; | 
|  | 52 | } | 
|  | 53 |  | 
| John Reck | 8ddbc59 | 2020-05-07 16:11:18 -0700 | [diff] [blame] | 54 | bool didSetExtraBuffers() const { | 
|  | 55 | std::lock_guard _lock{mMutex}; | 
|  | 56 | return mDidSetExtraBuffers; | 
|  | 57 | } | 
|  | 58 |  | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 59 | private: | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 60 | ANativeWindow* mWindow; | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 61 |  | 
|  | 62 | mutable std::mutex mMutex; | 
|  | 63 |  | 
|  | 64 | uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; | 
| Alec Mouri | 43fe6fc | 2019-12-23 07:46:19 -0800 | [diff] [blame] | 65 | AHardwareBuffer_Format mFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; | 
| Alec Mouri | 4523801 | 2020-01-29 11:04:40 -0800 | [diff] [blame] | 66 | UniqueAHardwareBuffer mScratchBuffer; | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 67 | ANativeWindowBuffer* mReservedBuffer = nullptr; | 
|  | 68 | base::unique_fd mReservedFenceFd; | 
|  | 69 | bool mHasDequeuedBuffer = false; | 
| John Reck | 59dd2ea | 2019-07-26 16:51:08 -0700 | [diff] [blame] | 70 | int mBufferQueueState = OK; | 
| John Reck | 8ddbc59 | 2020-05-07 16:11:18 -0700 | [diff] [blame] | 71 | size_t mExpectedBufferCount = 0; | 
|  | 72 | bool mDidSetExtraBuffers = false; | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 73 |  | 
|  | 74 | bool isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const; | 
| John Reck | 59dd2ea | 2019-07-26 16:51:08 -0700 | [diff] [blame] | 75 | ANativeWindowBuffer* acquireFallbackBuffer(int error); | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 76 | void clearReservedBuffer(); | 
|  | 77 |  | 
| Alec Mouri | f023a32 | 2019-11-25 10:02:21 -0800 | [diff] [blame] | 78 | // ANativeWindow hooks. When an ANativeWindow_* method is called on the | 
|  | 79 | // underlying ANativeWindow, these methods will intercept the original call. | 
|  | 80 | // For example, an EGL driver would call into these hooks instead of the | 
|  | 81 | // original methods. | 
|  | 82 | static int hook_cancelBuffer(ANativeWindow* window, ANativeWindow_cancelBufferFn cancelBuffer, | 
|  | 83 | void* data, ANativeWindowBuffer* buffer, int fenceFd); | 
|  | 84 | static int hook_dequeueBuffer(ANativeWindow* window, | 
|  | 85 | ANativeWindow_dequeueBufferFn dequeueBuffer, void* data, | 
|  | 86 | ANativeWindowBuffer** buffer, int* fenceFd); | 
|  | 87 | static int hook_queueBuffer(ANativeWindow* window, ANativeWindow_queueBufferFn queueBuffer, | 
|  | 88 | void* data, ANativeWindowBuffer* buffer, int fenceFd); | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 89 |  | 
| Alec Mouri | f023a32 | 2019-11-25 10:02:21 -0800 | [diff] [blame] | 90 | static int hook_perform(ANativeWindow* window, ANativeWindow_performFn perform, void* data, | 
|  | 91 | int operation, va_list args); | 
| John Reck | 8ddbc59 | 2020-05-07 16:11:18 -0700 | [diff] [blame] | 92 | static int hook_query(const ANativeWindow* window, ANativeWindow_queryFn query, void* data, | 
|  | 93 | int what, int* value); | 
| John Reck | 848f651 | 2018-12-03 13:26:43 -0800 | [diff] [blame] | 94 | }; | 
|  | 95 |  | 
| Alec Mouri | 8d0c5bd2 | 2019-08-22 19:20:41 -0700 | [diff] [blame] | 96 | };  // namespace android::uirenderer::renderthread |