| // Copyright 2024 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "ANativeWindowEmulated.h" |
| |
| #include <log/log.h> |
| |
| namespace gfxstream { |
| |
| EmulatedANativeWindow::EmulatedANativeWindow( |
| uint32_t width, uint32_t height, uint32_t format, |
| std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers) |
| : mRefCount(1), mWidth(width), mHeight(height), mFormat(format), mBuffers(std::move(buffers)) { |
| for (auto& buffer : mBuffers) { |
| mBufferQueue.push_back(QueuedAHB{ |
| .ahb = buffer.get(), |
| .fence = -1, |
| }); |
| } |
| } |
| |
| EGLNativeWindowType EmulatedANativeWindow::asEglNativeWindowType() { |
| return reinterpret_cast<EGLNativeWindowType>(this); |
| } |
| |
| uint32_t EmulatedANativeWindow::getWidth() const { return mWidth; } |
| |
| uint32_t EmulatedANativeWindow::getHeight() const { return mHeight; } |
| |
| int EmulatedANativeWindow::getFormat() const { return mFormat; } |
| |
| int EmulatedANativeWindow::queueBuffer(EGLClientBuffer buffer, int fence) { |
| auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); |
| |
| mBufferQueue.push_back(QueuedAHB{ |
| .ahb = ahb, |
| .fence = fence, |
| }); |
| |
| return 0; |
| } |
| |
| int EmulatedANativeWindow::dequeueBuffer(EGLClientBuffer* buffer, int* fence) { |
| auto queuedAhb = mBufferQueue.front(); |
| mBufferQueue.pop_front(); |
| |
| *buffer = queuedAhb.ahb->asEglClientBuffer(); |
| *fence = queuedAhb.fence; |
| return 0; |
| } |
| |
| int EmulatedANativeWindow::cancelBuffer(EGLClientBuffer buffer) { |
| auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); |
| |
| mBufferQueue.push_back(QueuedAHB{ |
| .ahb = ahb, |
| .fence = -1, |
| }); |
| |
| return 0; |
| } |
| |
| void EmulatedANativeWindow::acquire() { ++mRefCount; } |
| |
| void EmulatedANativeWindow::release() { |
| --mRefCount; |
| if (mRefCount == 0) { |
| delete this; |
| } |
| } |
| |
| bool EmulatedANativeWindowHelper::isValid(EGLNativeWindowType window) { |
| // TODO: maybe a registry of valid EmulatedANativeWindow-s? |
| (void)window; |
| return true; |
| } |
| |
| bool EmulatedANativeWindowHelper::isValid(EGLClientBuffer buffer) { |
| // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s? |
| (void)buffer; |
| return true; |
| } |
| |
| void EmulatedANativeWindowHelper::acquire(EGLNativeWindowType window) { |
| auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| anw->acquire(); |
| } |
| |
| void EmulatedANativeWindowHelper::release(EGLNativeWindowType window) { |
| auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| anw->release(); |
| } |
| |
| void EmulatedANativeWindowHelper::acquire(EGLClientBuffer buffer) { |
| // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s? |
| (void)buffer; |
| } |
| |
| void EmulatedANativeWindowHelper::release(EGLClientBuffer buffer) { (void)buffer; } |
| |
| int EmulatedANativeWindowHelper::getConsumerUsage(EGLNativeWindowType window, int* usage) { |
| (void)window; |
| (void)usage; |
| return 0; |
| } |
| void EmulatedANativeWindowHelper::setUsage(EGLNativeWindowType window, int usage) { |
| (void)window; |
| (void)usage; |
| } |
| |
| int EmulatedANativeWindowHelper::getWidth(EGLNativeWindowType window) { |
| auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| return anw->getWidth(); |
| } |
| |
| int EmulatedANativeWindowHelper::getHeight(EGLNativeWindowType window) { |
| auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| return anw->getHeight(); |
| } |
| |
| int EmulatedANativeWindowHelper::getWidth(EGLClientBuffer buffer) { |
| auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); |
| return ahb->getWidth(); |
| } |
| |
| int EmulatedANativeWindowHelper::getHeight(EGLClientBuffer buffer) { |
| auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); |
| return ahb->getHeight(); |
| } |
| |
| int EmulatedANativeWindowHelper::getFormat(EGLClientBuffer buffer, Gralloc* helper) { |
| (void)helper; |
| |
| auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); |
| return ahb->getAndroidFormat(); |
| } |
| |
| void EmulatedANativeWindowHelper::setSwapInterval(EGLNativeWindowType window, int interval) { |
| ALOGE("Unimplemented"); |
| (void)window; |
| (void)interval; |
| } |
| |
| int EmulatedANativeWindowHelper::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, |
| int fence) { |
| auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| return anw->queueBuffer(buffer, fence); |
| } |
| |
| int EmulatedANativeWindowHelper::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, |
| int* fence) { |
| auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| return anw->dequeueBuffer(buffer, fence); |
| } |
| |
| int EmulatedANativeWindowHelper::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) { |
| auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); |
| return anw->cancelBuffer(buffer); |
| } |
| |
| int EmulatedANativeWindowHelper::getHostHandle(EGLClientBuffer buffer, Gralloc*) { |
| auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); |
| return ahb->getResourceId(); |
| } |
| |
| EGLNativeWindowType EmulatedANativeWindowHelper::createNativeWindowForTesting(Gralloc* gralloc, |
| uint32_t width, |
| uint32_t height) { |
| std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers; |
| for (int i = 0; i < 3; i++) { |
| AHardwareBuffer* ahb = nullptr; |
| if (gralloc->allocate(width, height, GFXSTREAM_AHB_FORMAT_R8G8B8A8_UNORM, -1, &ahb) != 0) { |
| ALOGE("Failed to allocate gralloc buffer."); |
| return nullptr; |
| } |
| buffers.emplace_back(reinterpret_cast<EmulatedAHardwareBuffer*>(ahb)); |
| } |
| return reinterpret_cast<EGLNativeWindowType>( |
| new EmulatedANativeWindow(width, height, GFXSTREAM_AHB_FORMAT_R8G8B8A8_UNORM, std::move(buffers))); |
| } |
| |
| ANativeWindowHelper* createPlatformANativeWindowHelper() { |
| return new EmulatedANativeWindowHelper(); |
| } |
| |
| } // namespace gfxstream |