Merge commit '852f2a6343518919e5ca8d3c1bbcab9f493e3cd8'
This commit is contained in:
713
external/sdl/SDL/src/video/android/SDL_android_video_capture.c
vendored
Normal file
713
external/sdl/SDL/src/video/android/SDL_android_video_capture.c
vendored
Normal file
@ -0,0 +1,713 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "SDL3/SDL.h"
|
||||
#include "SDL3/SDL_video_capture.h"
|
||||
#include "../SDL_sysvideocapture.h"
|
||||
#include "../SDL_video_capture_c.h"
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
#define DEBUG_VIDEO_CAPTURE_CAPTURE 0
|
||||
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ >= 24
|
||||
|
||||
/*
|
||||
* APP_PLATFORM=android-24
|
||||
* minSdkVersion=24
|
||||
*
|
||||
* link with: -lcamera2ndk -lmediandk
|
||||
*
|
||||
* AndroidManifest.xml:
|
||||
* <uses-permission android:name="android.permission.CAMERA"></uses-permission>
|
||||
* <uses-feature android:name="android.hardware.camera" />
|
||||
*
|
||||
*
|
||||
* Add: #define SDL_VIDEO_CAPTURE 1
|
||||
* in: include/build_config/SDL_build_config_android.h
|
||||
*
|
||||
*
|
||||
* Very likely SDL must be build with YUV support (done by default)
|
||||
*
|
||||
* https://developer.android.com/reference/android/hardware/camera2/CameraManager
|
||||
* "All camera devices intended to be operated concurrently, must be opened using openCamera(String, CameraDevice.StateCallback, Handler),
|
||||
* before configuring sessions on any of the camera devices. * "
|
||||
*/
|
||||
|
||||
#include <camera/NdkCameraDevice.h>
|
||||
#include <camera/NdkCameraManager.h>
|
||||
#include <media/NdkImage.h>
|
||||
#include <media/NdkImageReader.h>
|
||||
|
||||
#include "../../core/android/SDL_android.h"
|
||||
|
||||
|
||||
static ACameraManager *cameraMgr = NULL;
|
||||
static ACameraIdList *cameraIdList = NULL;
|
||||
|
||||
static void
|
||||
create_cameraMgr(void)
|
||||
{
|
||||
if (cameraMgr == NULL) {
|
||||
|
||||
if (!Android_JNI_RequestPermission("android.permission.CAMERA")) {
|
||||
SDL_SetError("This app doesn't have CAMERA permission");
|
||||
return;
|
||||
}
|
||||
|
||||
cameraMgr = ACameraManager_create();
|
||||
if (cameraMgr == NULL) {
|
||||
SDL_Log("Error creating ACameraManager");
|
||||
} else {
|
||||
SDL_Log("Create ACameraManager");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_cameraMgr(void)
|
||||
{
|
||||
if (cameraIdList) {
|
||||
ACameraManager_deleteCameraIdList(cameraIdList);
|
||||
cameraIdList = NULL;
|
||||
}
|
||||
|
||||
if (cameraMgr) {
|
||||
ACameraManager_delete(cameraMgr);
|
||||
cameraMgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct SDL_PrivateVideoCaptureData
|
||||
{
|
||||
ACameraDevice *device;
|
||||
ACameraCaptureSession *session;
|
||||
ACameraDevice_StateCallbacks dev_callbacks;
|
||||
ACameraCaptureSession_stateCallbacks capture_callbacks;
|
||||
ACaptureSessionOutputContainer *sessionOutputContainer;
|
||||
AImageReader *reader;
|
||||
int num_formats;
|
||||
int count_formats[6]; // see format_2_id
|
||||
};
|
||||
|
||||
|
||||
/**/
|
||||
#define FORMAT_SDL SDL_PIXELFORMAT_NV12
|
||||
|
||||
static int
|
||||
format_2_id(int fmt) {
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case x: return y
|
||||
CASE(FORMAT_SDL, 0);
|
||||
CASE(SDL_PIXELFORMAT_RGB565, 1);
|
||||
CASE(SDL_PIXELFORMAT_XRGB8888, 2);
|
||||
CASE(SDL_PIXELFORMAT_RGBA8888, 3);
|
||||
CASE(SDL_PIXELFORMAT_RGBX8888, 4);
|
||||
CASE(SDL_PIXELFORMAT_UNKNOWN, 5);
|
||||
#undef CASE
|
||||
default:
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
id_2_format(int fmt) {
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case y: return x
|
||||
CASE(FORMAT_SDL, 0);
|
||||
CASE(SDL_PIXELFORMAT_RGB565, 1);
|
||||
CASE(SDL_PIXELFORMAT_XRGB8888, 2);
|
||||
CASE(SDL_PIXELFORMAT_RGBA8888, 3);
|
||||
CASE(SDL_PIXELFORMAT_RGBX8888, 4);
|
||||
CASE(SDL_PIXELFORMAT_UNKNOWN, 5);
|
||||
#undef CASE
|
||||
default:
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32
|
||||
format_android_2_sdl(Uint32 fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case x: return y
|
||||
CASE(AIMAGE_FORMAT_YUV_420_888, FORMAT_SDL);
|
||||
CASE(AIMAGE_FORMAT_RGB_565, SDL_PIXELFORMAT_RGB565);
|
||||
CASE(AIMAGE_FORMAT_RGB_888, SDL_PIXELFORMAT_XRGB8888);
|
||||
CASE(AIMAGE_FORMAT_RGBA_8888, SDL_PIXELFORMAT_RGBA8888);
|
||||
CASE(AIMAGE_FORMAT_RGBX_8888, SDL_PIXELFORMAT_RGBX8888);
|
||||
|
||||
CASE(AIMAGE_FORMAT_RGBA_FP16, SDL_PIXELFORMAT_UNKNOWN); // 64bits
|
||||
CASE(AIMAGE_FORMAT_RAW_PRIVATE, SDL_PIXELFORMAT_UNKNOWN);
|
||||
CASE(AIMAGE_FORMAT_JPEG, SDL_PIXELFORMAT_UNKNOWN);
|
||||
#undef CASE
|
||||
default:
|
||||
SDL_Log("Unknown format AIMAGE_FORMAT '%d'", fmt);
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32
|
||||
format_sdl_2_android(Uint32 fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case y: return x
|
||||
CASE(AIMAGE_FORMAT_YUV_420_888, FORMAT_SDL);
|
||||
CASE(AIMAGE_FORMAT_RGB_565, SDL_PIXELFORMAT_RGB565);
|
||||
CASE(AIMAGE_FORMAT_RGB_888, SDL_PIXELFORMAT_XRGB8888);
|
||||
CASE(AIMAGE_FORMAT_RGBA_8888, SDL_PIXELFORMAT_RGBA8888);
|
||||
CASE(AIMAGE_FORMAT_RGBX_8888, SDL_PIXELFORMAT_RGBX8888);
|
||||
#undef CASE
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
onDisconnected(void *context, ACameraDevice *device)
|
||||
{
|
||||
// SDL_VideoCaptureDevice *_this = (SDL_VideoCaptureDevice *) context;
|
||||
SDL_Log("CB onDisconnected");
|
||||
}
|
||||
|
||||
static void
|
||||
onError(void *context, ACameraDevice *device, int error)
|
||||
{
|
||||
// SDL_VideoCaptureDevice *_this = (SDL_VideoCaptureDevice *) context;
|
||||
SDL_Log("CB onError");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
onClosed(void* context, ACameraCaptureSession *session)
|
||||
{
|
||||
// SDL_VideoCaptureDevice *_this = (SDL_VideoCaptureDevice *) context;
|
||||
SDL_Log("CB onClosed");
|
||||
}
|
||||
|
||||
static void
|
||||
onReady(void* context, ACameraCaptureSession *session)
|
||||
{
|
||||
// SDL_VideoCaptureDevice *_this = (SDL_VideoCaptureDevice *) context;
|
||||
SDL_Log("CB onReady");
|
||||
}
|
||||
|
||||
static void
|
||||
onActive(void* context, ACameraCaptureSession *session)
|
||||
{
|
||||
// SDL_VideoCaptureDevice *_this = (SDL_VideoCaptureDevice *) context;
|
||||
SDL_Log("CB onActive");
|
||||
}
|
||||
|
||||
int
|
||||
OpenDevice(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
camera_status_t res;
|
||||
|
||||
/* Cannot open a second camera, while the first one is opened.
|
||||
* If you want to play several camera, they must all be opened first, then played.
|
||||
*
|
||||
* https://developer.android.com/reference/android/hardware/camera2/CameraManager
|
||||
* "All camera devices intended to be operated concurrently, must be opened using openCamera(String, CameraDevice.StateCallback, Handler),
|
||||
* before configuring sessions on any of the camera devices. * "
|
||||
*
|
||||
*/
|
||||
if (check_device_playing()) {
|
||||
return SDL_SetError("A camera is already playing");
|
||||
}
|
||||
|
||||
_this->hidden = (struct SDL_PrivateVideoCaptureData *) SDL_calloc(1, sizeof (struct SDL_PrivateVideoCaptureData));
|
||||
if (_this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
create_cameraMgr();
|
||||
|
||||
_this->hidden->dev_callbacks.context = (void *) _this;
|
||||
_this->hidden->dev_callbacks.onDisconnected = onDisconnected;
|
||||
_this->hidden->dev_callbacks.onError = onError;
|
||||
|
||||
res = ACameraManager_openCamera(cameraMgr, _this->dev_name, &_this->hidden->dev_callbacks, &_this->hidden->device);
|
||||
if (res != ACAMERA_OK) {
|
||||
return SDL_SetError("Failed to open camera");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CloseDevice(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
if (_this && _this->hidden) {
|
||||
if (_this->hidden->session) {
|
||||
ACameraCaptureSession_close(_this->hidden->session);
|
||||
}
|
||||
|
||||
if (_this->hidden->sessionOutputContainer) {
|
||||
ACaptureSessionOutputContainer_free(_this->hidden->sessionOutputContainer);
|
||||
}
|
||||
|
||||
if (_this->hidden->reader) {
|
||||
AImageReader_delete(_this->hidden->reader);
|
||||
}
|
||||
|
||||
if (_this->hidden->device) {
|
||||
ACameraDevice_close(_this->hidden->device);
|
||||
}
|
||||
|
||||
SDL_free(_this->hidden);
|
||||
|
||||
_this->hidden = NULL;
|
||||
}
|
||||
|
||||
if (check_all_device_closed()) {
|
||||
delete_cameraMgr();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
InitDevice(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
size_t size, pitch;
|
||||
SDL_CalculateSize(_this->spec.format, _this->spec.width, _this->spec.height, &size, &pitch, SDL_FALSE);
|
||||
SDL_Log("Buffer size: %d x %d", _this->spec.width, _this->spec.height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GetDeviceSpec(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureSpec *spec)
|
||||
{
|
||||
if (spec) {
|
||||
*spec = _this->spec;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
StartCapture(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
camera_status_t res;
|
||||
media_status_t res2;
|
||||
ANativeWindow *window = NULL;
|
||||
ACaptureSessionOutput *sessionOutput;
|
||||
ACameraOutputTarget *outputTarget;
|
||||
ACaptureRequest *request;
|
||||
|
||||
res2 = AImageReader_new(_this->spec.width, _this->spec.height, format_sdl_2_android(_this->spec.format), 10 /* nb buffers */, &_this->hidden->reader);
|
||||
if (res2 != AMEDIA_OK) {
|
||||
SDL_SetError("Error AImageReader_new");
|
||||
goto error;
|
||||
}
|
||||
res2 = AImageReader_getWindow(_this->hidden->reader, &window);
|
||||
if (res2 != AMEDIA_OK) {
|
||||
SDL_SetError("Error AImageReader_new");
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
|
||||
res = ACaptureSessionOutput_create(window, &sessionOutput);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACaptureSessionOutput_create");
|
||||
goto error;
|
||||
}
|
||||
res = ACaptureSessionOutputContainer_create(&_this->hidden->sessionOutputContainer);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACaptureSessionOutputContainer_create");
|
||||
goto error;
|
||||
}
|
||||
res = ACaptureSessionOutputContainer_add(_this->hidden->sessionOutputContainer, sessionOutput);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACaptureSessionOutputContainer_add");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
res = ACameraOutputTarget_create(window, &outputTarget);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACameraOutputTarget_create");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
res = ACameraDevice_createCaptureRequest(_this->hidden->device, TEMPLATE_RECORD, &request);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACameraDevice_createCaptureRequest");
|
||||
goto error;
|
||||
}
|
||||
|
||||
res = ACaptureRequest_addTarget(request, outputTarget);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACaptureRequest_addTarget");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
_this->hidden->capture_callbacks.context = (void *) _this;
|
||||
_this->hidden->capture_callbacks.onClosed = onClosed;
|
||||
_this->hidden->capture_callbacks.onReady = onReady;
|
||||
_this->hidden->capture_callbacks.onActive = onActive;
|
||||
|
||||
res = ACameraDevice_createCaptureSession(_this->hidden->device,
|
||||
_this->hidden->sessionOutputContainer,
|
||||
&_this->hidden->capture_callbacks,
|
||||
&_this->hidden->session);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACameraDevice_createCaptureSession");
|
||||
goto error;
|
||||
}
|
||||
|
||||
res = ACameraCaptureSession_setRepeatingRequest(_this->hidden->session, NULL, 1, &request, NULL);
|
||||
if (res != ACAMERA_OK) {
|
||||
SDL_SetError("Error ACameraDevice_createCaptureSession");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
StopCapture(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
ACameraCaptureSession_close(_this->hidden->session);
|
||||
_this->hidden->session = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AcquireFrame(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureFrame *frame)
|
||||
{
|
||||
media_status_t res;
|
||||
AImage *image;
|
||||
res = AImageReader_acquireNextImage(_this->hidden->reader, &image);
|
||||
/* We could also use this one:
|
||||
res = AImageReader_acquireLatestImage(_this->hidden->reader, &image);
|
||||
*/
|
||||
if (res == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE ) {
|
||||
|
||||
SDL_Delay(20); // TODO fix some delay
|
||||
#if DEBUG_VIDEO_CAPTURE_CAPTURE
|
||||
// SDL_Log("AImageReader_acquireNextImage: AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE");
|
||||
#endif
|
||||
return 0;
|
||||
} else if (res == AMEDIA_OK ) {
|
||||
int i = 0;
|
||||
int32_t numPlanes = 0;
|
||||
AImage_getNumberOfPlanes(image, &numPlanes);
|
||||
|
||||
frame->timestampNS = SDL_GetTicksNS();
|
||||
|
||||
for (i = 0; i < numPlanes && i < 3; i++) {
|
||||
int dataLength = 0;
|
||||
int rowStride = 0;
|
||||
uint8_t *data = NULL;
|
||||
frame->num_planes += 1;
|
||||
AImage_getPlaneRowStride(image, i, &rowStride);
|
||||
res = AImage_getPlaneData(image, i, &data, &dataLength);
|
||||
if (res == AMEDIA_OK) {
|
||||
frame->data[i] = data;
|
||||
frame->pitch[i] = rowStride;
|
||||
}
|
||||
}
|
||||
|
||||
if (frame->num_planes == 3) {
|
||||
/* plane 2 and 3 are interleaved NV12. SDL only takes two planes for this format */
|
||||
int pixelStride = 0;
|
||||
AImage_getPlanePixelStride(image, 1, &pixelStride);
|
||||
if (pixelStride == 2) {
|
||||
frame->num_planes -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
frame->internal = (void*)image;
|
||||
return 0;
|
||||
} else if (res == AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED) {
|
||||
SDL_SetError("AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED");
|
||||
} else {
|
||||
SDL_SetError("AImageReader_acquireNextImage: %d", res);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ReleaseFrame(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureFrame *frame)
|
||||
{
|
||||
if (frame->internal){
|
||||
AImage_delete((AImage *)frame->internal);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GetNumFormats(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
camera_status_t res;
|
||||
int i;
|
||||
int unknown = 0;
|
||||
ACameraMetadata *metadata;
|
||||
ACameraMetadata_const_entry entry;
|
||||
|
||||
if (_this->hidden->num_formats != 0) {
|
||||
return _this->hidden->num_formats;
|
||||
}
|
||||
|
||||
res = ACameraManager_getCameraCharacteristics(cameraMgr, _this->dev_name, &metadata);
|
||||
if (res != ACAMERA_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = ACameraMetadata_getConstEntry(metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
|
||||
if (res != ACAMERA_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Log("got entry ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS");
|
||||
|
||||
for (i = 0; i < entry.count; i += 4) {
|
||||
int32_t format = entry.data.i32[i + 0];
|
||||
int32_t type = entry.data.i32[i + 3];
|
||||
Uint32 fmt;
|
||||
|
||||
if (type == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fmt = format_android_2_sdl(format);
|
||||
_this->hidden->count_formats[format_2_id(fmt)] += 1;
|
||||
|
||||
#if DEBUG_VIDEO_CAPTURE_CAPTURE
|
||||
if (fmt != SDL_PIXELFORMAT_UNKNOWN) {
|
||||
int w = entry.data.i32[i + 1];
|
||||
int h = entry.data.i32[i + 2];
|
||||
SDL_Log("Got format android 0x%08x -> %s %d x %d", format, SDL_GetPixelFormatName(fmt), w, h);
|
||||
} else {
|
||||
unknown += 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG_VIDEO_CAPTURE_CAPTURE
|
||||
if (unknown) {
|
||||
SDL_Log("Got unknown android");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if ( _this->hidden->count_formats[0]) _this->hidden->num_formats += 1;
|
||||
if ( _this->hidden->count_formats[1]) _this->hidden->num_formats += 1;
|
||||
if ( _this->hidden->count_formats[2]) _this->hidden->num_formats += 1;
|
||||
if ( _this->hidden->count_formats[3]) _this->hidden->num_formats += 1;
|
||||
if ( _this->hidden->count_formats[4]) _this->hidden->num_formats += 1;
|
||||
if ( _this->hidden->count_formats[5]) _this->hidden->num_formats += 1;
|
||||
|
||||
return _this->hidden->num_formats;
|
||||
}
|
||||
|
||||
int
|
||||
GetFormat(SDL_VideoCaptureDevice *_this, int index, Uint32 *format)
|
||||
{
|
||||
int i;
|
||||
int i2 = 0;
|
||||
|
||||
if (_this->hidden->num_formats == 0) {
|
||||
GetNumFormats(_this);
|
||||
}
|
||||
|
||||
if (index < 0 || index >= _this->hidden->num_formats) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(_this->hidden->count_formats); i++) {
|
||||
if (_this->hidden->count_formats[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i2 == index) {
|
||||
*format = id_2_format(i);
|
||||
}
|
||||
|
||||
i2++;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GetNumFrameSizes(SDL_VideoCaptureDevice *_this, Uint32 format)
|
||||
{
|
||||
int i, i2 = 0, index;
|
||||
if (_this->hidden->num_formats == 0) {
|
||||
GetNumFormats(_this);
|
||||
}
|
||||
|
||||
index = format_2_id(format);
|
||||
|
||||
for (i = 0; i < SDL_arraysize(_this->hidden->count_formats); i++) {
|
||||
if (_this->hidden->count_formats[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i2 == index) {
|
||||
/* number of resolution for this format */
|
||||
return _this->hidden->count_formats[i];
|
||||
}
|
||||
|
||||
i2++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width, int *height)
|
||||
{
|
||||
camera_status_t res;
|
||||
int i, i2 = 0;
|
||||
ACameraMetadata *metadata;
|
||||
ACameraMetadata_const_entry entry;
|
||||
|
||||
if (_this->hidden->num_formats == 0) {
|
||||
GetNumFormats(_this);
|
||||
}
|
||||
|
||||
res = ACameraManager_getCameraCharacteristics(cameraMgr, _this->dev_name, &metadata);
|
||||
if (res != ACAMERA_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = ACameraMetadata_getConstEntry(metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
|
||||
if (res != ACAMERA_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < entry.count; i += 4) {
|
||||
int32_t f = entry.data.i32[i + 0];
|
||||
int w = entry.data.i32[i + 1];
|
||||
int h = entry.data.i32[i + 2];
|
||||
int32_t type = entry.data.i32[i + 3];
|
||||
Uint32 fmt;
|
||||
|
||||
if (type == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
fmt = format_android_2_sdl(f);
|
||||
if (fmt != format) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i2 == index) {
|
||||
*width = w;
|
||||
*height = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
i2++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int GetNumDevices(void);
|
||||
|
||||
int
|
||||
GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size)
|
||||
{
|
||||
int index = instance_id - 1;
|
||||
create_cameraMgr();
|
||||
|
||||
if (cameraIdList == NULL) {
|
||||
GetNumDevices();
|
||||
}
|
||||
|
||||
if (cameraIdList) {
|
||||
if (index >= 0 && index < cameraIdList->numCameras) {
|
||||
SDL_snprintf(buf, size, "%s", cameraIdList->cameraIds[index]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
GetNumDevices(void)
|
||||
{
|
||||
camera_status_t res;
|
||||
create_cameraMgr();
|
||||
|
||||
if (cameraIdList) {
|
||||
ACameraManager_deleteCameraIdList(cameraIdList);
|
||||
cameraIdList = NULL;
|
||||
}
|
||||
|
||||
res = ACameraManager_getCameraIdList(cameraMgr, &cameraIdList);
|
||||
|
||||
if (res == ACAMERA_OK) {
|
||||
if (cameraIdList) {
|
||||
return cameraIdList->numCameras;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_VideoCaptureDeviceID *GetVideoCaptureDevices(int *count)
|
||||
{
|
||||
/* hard-coded list of ID */
|
||||
int i;
|
||||
int num = GetNumDevices();
|
||||
SDL_VideoCaptureDeviceID *ret;
|
||||
|
||||
ret = (SDL_VideoCaptureDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret[i] = i + 1;
|
||||
}
|
||||
ret[num] = 0;
|
||||
*count = num;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureInit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureQuit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -45,6 +45,7 @@ static void android_egl_context_restore(SDL_Window *window)
|
||||
if (window) {
|
||||
SDL_Event event;
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_GL_MakeCurrent(window, NULL);
|
||||
if (SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context) < 0) {
|
||||
/* The context is no longer valid, create a new one */
|
||||
data->egl_context = (EGLContext)SDL_GL_CreateContext(window);
|
||||
@ -107,7 +108,7 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
#endif
|
||||
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
OPENSLES_PauseDevices();
|
||||
AAUDIO_PauseDevices();
|
||||
|
||||
if (SDL_WaitSemaphore(Android_ResumeSem) == 0) {
|
||||
@ -118,7 +119,7 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND);
|
||||
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
openslES_ResumeDevices();
|
||||
OPENSLES_ResumeDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
@ -131,8 +132,9 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
#endif
|
||||
|
||||
/* Make sure SW Keyboard is restored when an app becomes foreground */
|
||||
if (SDL_TextInputActive()) {
|
||||
Android_StartTextInput(_this); /* Only showTextInput */
|
||||
if (SDL_TextInputActive() &&
|
||||
SDL_GetHintBoolean(SDL_HINT_ENABLE_SCREEN_KEYBOARD, SDL_TRUE)) {
|
||||
Android_ShowScreenKeyboard(_this, Android_Window); /* Only showTextInput */
|
||||
}
|
||||
|
||||
SDL_SendAppEvent(SDL_EVENT_DID_ENTER_FOREGROUND);
|
||||
@ -159,11 +161,6 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AAUDIO_DetectBrokenPlayState()) {
|
||||
AAUDIO_PauseDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
}
|
||||
}
|
||||
|
||||
void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
@ -186,7 +183,7 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
|
||||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
OPENSLES_PauseDevices();
|
||||
AAUDIO_PauseDevices();
|
||||
}
|
||||
|
||||
@ -202,7 +199,7 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
|
||||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
openslES_ResumeDevices();
|
||||
OPENSLES_ResumeDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
}
|
||||
|
||||
@ -216,8 +213,9 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
#endif
|
||||
|
||||
/* Make sure SW Keyboard is restored when an app becomes foreground */
|
||||
if (SDL_TextInputActive()) {
|
||||
Android_StartTextInput(_this); /* Only showTextInput */
|
||||
if (SDL_TextInputActive() &&
|
||||
SDL_GetHintBoolean(SDL_HINT_ENABLE_SCREEN_KEYBOARD, SDL_TRUE)) {
|
||||
Android_ShowScreenKeyboard(_this, Android_Window); /* Only showTextInput */
|
||||
}
|
||||
|
||||
SDL_SendAppEvent(SDL_EVENT_DID_ENTER_FOREGROUND);
|
||||
@ -245,11 +243,6 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AAUDIO_DetectBrokenPlayState()) {
|
||||
AAUDIO_PauseDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_ANDROID */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -341,22 +341,22 @@ SDL_bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void Android_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoData *videodata = _this->driverdata;
|
||||
Android_JNI_ShowScreenKeyboard(&videodata->textRect);
|
||||
}
|
||||
|
||||
void Android_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
Android_JNI_HideScreenKeyboard();
|
||||
}
|
||||
|
||||
SDL_bool Android_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
return Android_JNI_IsScreenKeyboardShown();
|
||||
}
|
||||
|
||||
void Android_StartTextInput(SDL_VideoDevice *_this)
|
||||
{
|
||||
SDL_VideoData *videodata = _this->driverdata;
|
||||
Android_JNI_ShowTextInput(&videodata->textRect);
|
||||
}
|
||||
|
||||
void Android_StopTextInput(SDL_VideoDevice *_this)
|
||||
{
|
||||
Android_JNI_HideTextInput();
|
||||
}
|
||||
|
||||
int Android_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect)
|
||||
{
|
||||
SDL_VideoData *videodata = _this->driverdata;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -26,8 +26,7 @@ extern int Android_OnKeyDown(int keycode);
|
||||
extern int Android_OnKeyUp(int keycode);
|
||||
|
||||
extern SDL_bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
|
||||
extern void Android_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Android_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern SDL_bool Android_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
extern void Android_StartTextInput(SDL_VideoDevice *_this);
|
||||
extern void Android_StopTextInput(SDL_VideoDevice *_this);
|
||||
extern int Android_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -68,10 +68,7 @@ static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor)
|
||||
} else {
|
||||
SDL_free(cursor);
|
||||
cursor = NULL;
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
return cursor;
|
||||
@ -88,7 +85,7 @@ static SDL_Cursor *Android_CreateCursor(SDL_Surface *surface, int hot_x, int hot
|
||||
SDL_Surface *converted;
|
||||
|
||||
converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888);
|
||||
if (converted == NULL) {
|
||||
if (!converted) {
|
||||
return NULL;
|
||||
}
|
||||
custom_cursor = Android_JNI_CreateCustomCursor(converted, hot_x, hot_y);
|
||||
@ -117,7 +114,7 @@ static void Android_FreeCursor(SDL_Cursor *cursor)
|
||||
|
||||
static SDL_Cursor *Android_CreateEmptyCursor()
|
||||
{
|
||||
if (empty_cursor == NULL) {
|
||||
if (!empty_cursor) {
|
||||
SDL_Surface *empty_surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888);
|
||||
if (empty_surface) {
|
||||
SDL_memset(empty_surface->pixels, 0, (size_t)empty_surface->h * empty_surface->pitch);
|
||||
@ -138,7 +135,7 @@ static void Android_DestroyEmptyCursor()
|
||||
|
||||
static int Android_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
if (cursor == NULL) {
|
||||
if (!cursor) {
|
||||
cursor = Android_CreateEmptyCursor();
|
||||
}
|
||||
if (cursor) {
|
||||
@ -215,7 +212,7 @@ void Android_OnMouse(SDL_Window *window, int state, int action, float x, float y
|
||||
int changes;
|
||||
Uint8 button;
|
||||
|
||||
if (window == NULL) {
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -52,7 +52,7 @@ void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_fin
|
||||
SDL_TouchID touchDeviceId = 0;
|
||||
SDL_FingerID fingerId = 0;
|
||||
|
||||
if (window == NULL) {
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -86,14 +86,12 @@ static SDL_VideoDevice *Android_CreateDevice(void)
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (device == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
if (!device) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
|
||||
if (data == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
if (!data) {
|
||||
SDL_free(device);
|
||||
return NULL;
|
||||
}
|
||||
@ -117,7 +115,6 @@ static SDL_VideoDevice *Android_CreateDevice(void)
|
||||
device->MinimizeWindow = Android_MinimizeWindow;
|
||||
device->SetWindowResizable = Android_SetWindowResizable;
|
||||
device->DestroyWindow = Android_DestroyWindow;
|
||||
device->GetWindowWMInfo = Android_GetWindowWMInfo;
|
||||
|
||||
device->free = Android_DeleteDevice;
|
||||
|
||||
@ -145,12 +142,12 @@ static SDL_VideoDevice *Android_CreateDevice(void)
|
||||
device->SuspendScreenSaver = Android_SuspendScreenSaver;
|
||||
|
||||
/* Text input */
|
||||
device->StartTextInput = Android_StartTextInput;
|
||||
device->StopTextInput = Android_StopTextInput;
|
||||
device->SetTextInputRect = Android_SetTextInputRect;
|
||||
|
||||
/* Screen keyboard */
|
||||
device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport;
|
||||
device->ShowScreenKeyboard = Android_ShowScreenKeyboard;
|
||||
device->HideScreenKeyboard = Android_HideScreenKeyboard;
|
||||
device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
|
||||
|
||||
/* Clipboard */
|
||||
@ -158,6 +155,8 @@ static SDL_VideoDevice *Android_CreateDevice(void)
|
||||
device->GetClipboardText = Android_GetClipboardText;
|
||||
device->HasClipboardText = Android_HasClipboardText;
|
||||
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -35,7 +35,6 @@
|
||||
|
||||
#include "SDL_androidvulkan.h"
|
||||
|
||||
#include <SDL3/SDL_syswm.h>
|
||||
|
||||
int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
|
||||
{
|
||||
@ -49,10 +48,10 @@ int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
|
||||
}
|
||||
|
||||
/* Load the Vulkan loader library */
|
||||
if (path == NULL) {
|
||||
if (!path) {
|
||||
path = SDL_getenv("SDL_VULKAN_LIBRARY");
|
||||
}
|
||||
if (path == NULL) {
|
||||
if (!path) {
|
||||
path = "libvulkan.so";
|
||||
}
|
||||
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
|
||||
@ -77,7 +76,7 @@ int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
|
||||
(PFN_vkEnumerateInstanceExtensionProperties)
|
||||
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
|
||||
&extensionCount);
|
||||
if (extensions == NULL) {
|
||||
if (!extensions) {
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < extensionCount; i++) {
|
||||
@ -111,25 +110,22 @@ void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
|
||||
unsigned *count,
|
||||
const char **names)
|
||||
char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
|
||||
Uint32 *count)
|
||||
{
|
||||
static const char *const extensionsForAndroid[] = {
|
||||
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
|
||||
};
|
||||
if (!_this->vulkan_config.loader_handle) {
|
||||
SDL_SetError("Vulkan is not loaded");
|
||||
return SDL_FALSE;
|
||||
if(count) {
|
||||
*count = SDL_arraysize(extensionsForAndroid);
|
||||
}
|
||||
return SDL_Vulkan_GetInstanceExtensions_Helper(
|
||||
count, names, SDL_arraysize(extensionsForAndroid),
|
||||
extensionsForAndroid);
|
||||
return extensionsForAndroid;
|
||||
}
|
||||
|
||||
SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
|
||||
SDL_Window *window,
|
||||
VkInstance instance,
|
||||
const struct VkAllocationCallbacks *allocator,
|
||||
VkSurfaceKHR *surface)
|
||||
{
|
||||
SDL_WindowData *windowData = window->driverdata;
|
||||
@ -157,8 +153,7 @@ SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.window = windowData->native_window;
|
||||
result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
|
||||
NULL, surface);
|
||||
result = vkCreateAndroidSurfaceKHR(instance, &createInfo, allocator, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -36,12 +36,12 @@
|
||||
|
||||
int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
|
||||
void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
|
||||
SDL_bool Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
|
||||
unsigned *count,
|
||||
const char **names);
|
||||
char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
|
||||
Uint32 *count);
|
||||
SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
|
||||
SDL_Window *window,
|
||||
VkInstance instance,
|
||||
const struct VkAllocationCallbacks *allocator,
|
||||
VkSurfaceKHR *surface);
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -31,12 +31,11 @@
|
||||
#include "SDL_androidvideo.h"
|
||||
#include "SDL_androidwindow.h"
|
||||
|
||||
#include <SDL3/SDL_syswm.h>
|
||||
|
||||
/* Currently only one window */
|
||||
SDL_Window *Android_Window = NULL;
|
||||
|
||||
int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
|
||||
{
|
||||
SDL_WindowData *data;
|
||||
int retval = 0;
|
||||
@ -62,18 +61,18 @@ int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
data = (SDL_WindowData *)SDL_calloc(1, sizeof(*data));
|
||||
if (data == NULL) {
|
||||
retval = SDL_OutOfMemory();
|
||||
if (!data) {
|
||||
retval = -1;
|
||||
goto endfunction;
|
||||
}
|
||||
|
||||
data->native_window = Android_JNI_GetNativeWindow();
|
||||
|
||||
if (!data->native_window) {
|
||||
SDL_free(data);
|
||||
retval = SDL_SetError("Could not fetch native window");
|
||||
goto endfunction;
|
||||
}
|
||||
SDL_SetProperty(SDL_GetWindowProperties(window), SDL_PROPERTY_WINDOW_ANDROID_WINDOW_POINTER, data->native_window);
|
||||
|
||||
/* Do not create EGLSurface for Vulkan window since it will then make the window
|
||||
incompatible with vkCreateAndroidSurfaceKHR */
|
||||
@ -88,6 +87,7 @@ int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
goto endfunction;
|
||||
}
|
||||
}
|
||||
SDL_SetProperty(SDL_GetWindowProperties(window), SDL_PROPERTY_WINDOW_ANDROID_SURFACE_POINTER, data->egl_surface);
|
||||
#endif
|
||||
|
||||
window->driverdata = data;
|
||||
@ -105,7 +105,7 @@ void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
Android_JNI_SetActivityTitle(window->title);
|
||||
}
|
||||
|
||||
void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
int Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
|
||||
@ -129,7 +129,7 @@ void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL
|
||||
}
|
||||
|
||||
data = window->driverdata;
|
||||
if (data == NULL || !data->native_window) {
|
||||
if (!data || !data->native_window) {
|
||||
if (data && !data->native_window) {
|
||||
SDL_SetError("Missing native window");
|
||||
}
|
||||
@ -154,6 +154,7 @@ void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL
|
||||
endfunction:
|
||||
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
@ -194,18 +195,4 @@ void Android_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
|
||||
int Android_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, SDL_SysWMinfo *info)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
|
||||
info->subsystem = SDL_SYSWM_ANDROID;
|
||||
info->info.android.window = data->native_window;
|
||||
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
info->info.android.surface = data->egl_surface;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_ANDROID */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -26,14 +26,13 @@
|
||||
#include "../../core/android/SDL_android.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
|
||||
extern int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
|
||||
extern void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
|
||||
extern void Android_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern int Android_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, struct SDL_SysWMinfo *info);
|
||||
extern SDL_Window *Android_Window;
|
||||
|
||||
struct SDL_WindowData
|
||||
|
Reference in New Issue
Block a user