You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
9.7 KiB
290 lines
9.7 KiB
// Copyright 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 "AndroidWindow.h"
|
|
|
|
#include "AndroidHostCommon.h"
|
|
|
|
#include <errno.h>
|
|
#include <hardware/gralloc.h>
|
|
#include <stdio.h>
|
|
#include <cassert>
|
|
|
|
#define AW_DEBUG 1
|
|
|
|
#define E(fmt,...) \
|
|
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
|
|
|
|
#if AW_DEBUG
|
|
#define D(fmt,...) \
|
|
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
|
|
|
|
#else
|
|
#define D(fmt,...)
|
|
#endif
|
|
|
|
namespace aemu {
|
|
|
|
// Declarations for the ANativeWindow implementation.
|
|
|
|
static int hook_setSwapInterval(struct ANativeWindow* window, int interval);
|
|
static int hook_dequeueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer);
|
|
static int hook_lockBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
|
|
static int hook_queueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
|
|
static int hook_query(const struct ANativeWindow* window, int what, int* value);
|
|
static int hook_perform(struct ANativeWindow* window, int operation, ... );
|
|
static int hook_cancelBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
|
|
static int hook_dequeueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer, int* fenceFd);
|
|
static int hook_queueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd);
|
|
static int hook_cancelBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd);
|
|
static void hook_incRef(struct android_native_base_t* common);
|
|
static void hook_decRef(struct android_native_base_t* common);
|
|
|
|
AndroidWindow::AndroidWindow(int _width, int _height)
|
|
: width(_width), height(_height) {
|
|
// Initialize the ANativeWindow function pointers.
|
|
ANativeWindow::setSwapInterval = hook_setSwapInterval;
|
|
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
|
|
ANativeWindow::cancelBuffer = hook_cancelBuffer;
|
|
ANativeWindow::queueBuffer = hook_queueBuffer;
|
|
ANativeWindow::query = hook_query;
|
|
ANativeWindow::perform = hook_perform;
|
|
|
|
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
|
|
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
|
|
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
|
|
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
|
|
|
|
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
|
|
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
|
|
|
|
common.incRef = hook_incRef;
|
|
common.decRef = hook_decRef;
|
|
}
|
|
|
|
void AndroidWindow::setProducer(AndroidBufferQueue* _fromProducer,
|
|
AndroidBufferQueue* _toProducer) {
|
|
fromProducer = _fromProducer;
|
|
toProducer = _toProducer;
|
|
}
|
|
|
|
int AndroidWindow::dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd) {
|
|
assert(fromProducer);
|
|
AndroidBufferQueue::Item item;
|
|
fromProducer->dequeueBuffer(&item);
|
|
*buffer = item.buffer;
|
|
if (fenceFd)
|
|
*fenceFd = item.fenceFd;
|
|
return 0;
|
|
}
|
|
|
|
int AndroidWindow::queueBuffer(ANativeWindowBuffer* buffer, int fenceFd) {
|
|
assert(toProducer);
|
|
toProducer->queueBuffer({buffer, fenceFd});
|
|
return 0;
|
|
}
|
|
|
|
int AndroidWindow::cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd) {
|
|
assert(toProducer);
|
|
fromProducer->cancelBuffer({buffer, fenceFd});
|
|
return 0;
|
|
}
|
|
|
|
int AndroidWindow::query(int what, int* value) const {
|
|
switch (what) {
|
|
case ANATIVEWINDOW_QUERY_DEFAULT_WIDTH:
|
|
case NATIVE_WINDOW_WIDTH:
|
|
*value = width;
|
|
break;
|
|
case ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT:
|
|
case NATIVE_WINDOW_HEIGHT:
|
|
*value = height;
|
|
break;
|
|
case NATIVE_WINDOW_FORMAT:
|
|
*value = HAL_PIXEL_FORMAT_RGBA_8888;
|
|
break;
|
|
case NATIVE_WINDOW_TRANSFORM_HINT:
|
|
*value = 0;
|
|
break;
|
|
case NATIVE_WINDOW_MAX_BUFFER_COUNT:
|
|
*value = 2;
|
|
break;
|
|
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
|
|
*value = 2;
|
|
break;
|
|
|
|
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
|
|
case NATIVE_WINDOW_CONCRETE_TYPE:
|
|
case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
|
|
case NATIVE_WINDOW_BUFFER_AGE:
|
|
case NATIVE_WINDOW_LAST_DEQUEUE_DURATION:
|
|
case NATIVE_WINDOW_LAST_QUEUE_DURATION:
|
|
case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT:
|
|
case NATIVE_WINDOW_IS_VALID:
|
|
case NATIVE_WINDOW_DATASPACE:
|
|
default:
|
|
E("Unknown query 0x%x, not implemented.", what);
|
|
return -EINVAL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int AndroidWindow::perform(int operation, va_list args)
|
|
{
|
|
int res = 0;
|
|
switch (operation) {
|
|
case NATIVE_WINDOW_CONNECT:
|
|
// deprecated. must return NO_ERROR.
|
|
break;
|
|
case NATIVE_WINDOW_DISCONNECT:
|
|
// deprecated. must return NO_ERROR.
|
|
break;
|
|
case NATIVE_WINDOW_GET_CONSUMER_USAGE64: {
|
|
uint64_t* usage = va_arg(args, uint64_t*);
|
|
*usage =
|
|
GRALLOC_USAGE_HW_TEXTURE |
|
|
GRALLOC_USAGE_HW_RENDER;
|
|
va_end(args);
|
|
break;
|
|
}
|
|
case NATIVE_WINDOW_API_CONNECT:
|
|
case NATIVE_WINDOW_API_DISCONNECT: {
|
|
break;
|
|
}
|
|
case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT: {
|
|
bool* outSupport = va_arg(args, bool*);
|
|
*outSupport = false;
|
|
va_end(args);
|
|
break;
|
|
}
|
|
case NATIVE_WINDOW_SET_BUFFER_COUNT: {
|
|
size_t bufferCount = va_arg(args, size_t);
|
|
va_end(args);
|
|
break;
|
|
}
|
|
case NATIVE_WINDOW_SET_AUTO_REFRESH:
|
|
case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
|
|
case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
|
|
case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
|
|
case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
|
|
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
|
|
case NATIVE_WINDOW_SET_SCALING_MODE:
|
|
case NATIVE_WINDOW_SET_USAGE:
|
|
case NATIVE_WINDOW_SET_USAGE64:
|
|
case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION:
|
|
case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
|
|
break;
|
|
case NATIVE_WINDOW_SET_CROP:
|
|
case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
|
|
case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
|
|
case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
|
|
case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
|
|
case NATIVE_WINDOW_LOCK:
|
|
case NATIVE_WINDOW_UNLOCK_AND_POST:
|
|
case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
|
|
case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA:
|
|
case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
|
|
// case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
|
|
case NATIVE_WINDOW_GET_NEXT_FRAME_ID:
|
|
case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS:
|
|
case NATIVE_WINDOW_GET_COMPOSITOR_TIMING:
|
|
case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
|
|
case NATIVE_WINDOW_GET_HDR_SUPPORT:
|
|
|
|
default:
|
|
E("Unknown perform 0x%x, not implemented.", operation);
|
|
res = -EINVAL;
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// Android native window implementation
|
|
static int hook_setSwapInterval(struct ANativeWindow* window, int interval) {
|
|
AndroidWindow* aw = AndroidWindow::getSelf(window);
|
|
aw->swapInterval = interval;
|
|
return 0;
|
|
}
|
|
|
|
static int hook_dequeueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer) {
|
|
AndroidWindow* aw = AndroidWindow::getSelf(window);
|
|
return aw->dequeueBuffer(buffer, nullptr);
|
|
}
|
|
|
|
static int hook_lockBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer) {
|
|
E("Not implemented");
|
|
return 0;
|
|
}
|
|
|
|
static int hook_queueBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer) {
|
|
E("Not implemented");
|
|
return 0;
|
|
}
|
|
|
|
static int hook_query(const struct ANativeWindow* window, int what, int* value) {
|
|
const AndroidWindow* aw = AndroidWindow::getSelfConst(window);
|
|
return aw->query(what, value);
|
|
}
|
|
|
|
static int hook_perform(struct ANativeWindow* window, int operation, ... ) {
|
|
va_list args;
|
|
va_start(args, operation);
|
|
AndroidWindow* w = AndroidWindow::getSelf(window);
|
|
int result = w->perform(operation, args);
|
|
va_end(args);
|
|
return result;
|
|
}
|
|
|
|
static int hook_cancelBuffer_DEPRECATED(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer) {
|
|
E("Not implemented");
|
|
return 0;
|
|
}
|
|
|
|
static int hook_dequeueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer, int* fenceFd) {
|
|
AndroidWindow* aw = AndroidWindow::getSelf(window);
|
|
return aw->dequeueBuffer(buffer, fenceFd);
|
|
}
|
|
|
|
static int hook_queueBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd) {
|
|
AndroidWindow* aw = AndroidWindow::getSelf(window);
|
|
return aw->queueBuffer(buffer, fenceFd);
|
|
}
|
|
|
|
static int hook_cancelBuffer(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd) {
|
|
AndroidWindow* aw = AndroidWindow::getSelf(window);
|
|
return aw->cancelBuffer(buffer, fenceFd);
|
|
}
|
|
|
|
static void hook_incRef(struct android_native_base_t* common) {
|
|
}
|
|
|
|
static void hook_decRef(struct android_native_base_t* common) {
|
|
}
|
|
|
|
} // namespace aemu
|
|
|
|
extern "C" {
|
|
|
|
EXPORT ANativeWindow* create_host_anativewindow(int width, int height) {
|
|
aemu::AndroidWindow* res =
|
|
new aemu::AndroidWindow(width, height);
|
|
|
|
return (ANativeWindow*)res;
|
|
}
|
|
|
|
EXPORT void destroy_host_anativewindow(ANativeWindow* window) {
|
|
delete aemu::AndroidWindow::getSelf(window);
|
|
}
|
|
|
|
} // extern "C"
|