blob: ce47551794718c44b141f5462319f3ff8e76c38a [file] [log] [blame]
// 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