Release Vulpes OS 2.7-preview.24

This commit is contained in:
OverSu 2026-11-04 12:52:20 +01:00
commit 97ef99f827
135 changed files with 7717 additions and 2524 deletions

View file

@ -0,0 +1,175 @@
// SPDX-License-Identifier: MPL-2.0
// Bounded Android API 23 Camera1 diagnostic using an EGL/GLConsumer output path.
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
#include <binder/ProcessState.h>
#include <gui/BufferQueue.h>
#include <gui/GLConsumer.h>
#include <gui/GraphicBufferAlloc.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <utils/String16.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#ifndef GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif
static GLuint compileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, nullptr);
glCompileShader(shader);
GLint ok = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
if (!ok) {
char log[1024];
glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
fprintf(stderr, "shader_error=%s\n", log);
return 0;
}
return shader;
}
int main() {
setvbuf(stderr, nullptr, _IONBF, 0);
android::ProcessState::self()->startThreadPool();
const int cameraCount = android::Camera::getNumberOfCameras();
fprintf(stderr, "camera_count=%d uid=%d\n", cameraCount, getuid());
if (cameraCount < 1) return 2;
android::sp<android::Camera> camera = android::Camera::connect(
0, android::String16("org.vulpes.camera.glprobe"),
android::Camera::USE_CALLING_UID);
if (camera == nullptr) {
fprintf(stderr, "camera_connect_failed\n");
return 3;
}
android::CameraParameters parameters(camera->getParameters());
int width = 0;
int height = 0;
parameters.getPreviewSize(&width, &height);
fprintf(stderr, "stock_preview_size=%dx%d format=%s\n", width, height,
parameters.getPreviewFormat());
if (width <= 0 || height <= 0 || width > 1920 || height > 1920) return 4;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGLint major = 0, minor = 0;
if (display == EGL_NO_DISPLAY || !eglInitialize(display, &major, &minor)) {
fprintf(stderr, "egl_initialize_error=%x\n", eglGetError());
return 5;
}
const EGLint configAttributes[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_NONE};
EGLConfig config;
EGLint configCount = 0;
if (!eglChooseConfig(display, configAttributes, &config, 1, &configCount) ||
configCount < 1) return 6;
const EGLint surfaceAttributes[] = {
EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE};
EGLSurface surface = eglCreatePbufferSurface(display, config, surfaceAttributes);
const EGLint contextAttributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT,
contextAttributes);
if (surface == EGL_NO_SURFACE || context == EGL_NO_CONTEXT ||
!eglMakeCurrent(display, surface, surface, context)) {
fprintf(stderr, "egl_context_error=%x\n", eglGetError());
return 7;
}
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
android::sp<android::IGraphicBufferProducer> producer;
android::sp<android::IGraphicBufferConsumer> consumer;
android::sp<android::GraphicBufferAlloc> allocator =
new android::GraphicBufferAlloc();
android::BufferQueue::createBufferQueue(&producer, &consumer, allocator);
consumer->setDefaultBufferSize(width, height);
android::sp<android::GLConsumer> glConsumer = new android::GLConsumer(
consumer, texture, GL_TEXTURE_EXTERNAL_OES, true, false);
const int targetStatus = camera->setPreviewTarget(producer);
fprintf(stderr, "set_preview_target=%d\n", targetStatus);
const int startStatus = camera->startPreview();
fprintf(stderr, "start_preview=%d\n", startStatus);
if (targetStatus || startStatus) return 8;
const char* vertexSource =
"attribute vec4 a; attribute vec2 t; varying vec2 v;"
"void main(){gl_Position=a;v=t;}";
const char* fragmentSource =
"#extension GL_OES_EGL_image_external : require\n"
"precision mediump float; uniform samplerExternalOES s; varying vec2 v;"
"void main(){gl_FragColor=texture2D(s,v);}";
GLuint program = glCreateProgram();
GLuint vertex = compileShader(GL_VERTEX_SHADER, vertexSource);
GLuint fragment = compileShader(GL_FRAGMENT_SHADER, fragmentSource);
if (!vertex || !fragment) return 9;
glAttachShader(program, vertex);
glAttachShader(program, fragment);
glBindAttribLocation(program, 0, "a");
glBindAttribLocation(program, 1, "t");
glLinkProgram(program);
GLint linked = 0;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
char log[1024];
glGetProgramInfoLog(program, sizeof(log), nullptr, log);
fprintf(stderr, "program_link_error=%s\n", log);
return 10;
}
const GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
const GLfloat texcoords[] = {0, 1, 1, 1, 0, 0, 1, 0};
glUseProgram(program);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
glEnableVertexAttribArray(1);
glUniform1i(glGetUniformLocation(program, "s"), 0);
bool captured = false;
for (int attempt = 0; attempt < 100 && !captured; ++attempt) {
usleep(100000);
const int updateStatus = glConsumer->updateTexImage();
if (updateStatus != 0) continue;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glFinish();
unsigned char* pixels = new unsigned char[width * height * 3];
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
const GLenum glError = glGetError();
if (glError == GL_NO_ERROR) {
FILE* output = fopen("/data/local/tmp/vulpes-camera-glconsumer.ppm", "wb");
if (output) {
fprintf(output, "P6\n%d %d\n255\n", width, height);
for (int y = height - 1; y >= 0; --y)
fwrite(pixels + y * width * 3, 3, width, output);
fclose(output);
chmod("/data/local/tmp/vulpes-camera-glconsumer.ppm", 0644);
captured = true;
}
}
delete[] pixels;
fprintf(stderr, "update=%d gl_error=%x captured=%d\n",
updateStatus, glError, captured);
}
fprintf(stderr, "stopping_preview\n");
camera->stopPreview();
fprintf(stderr, "disconnecting_camera\n");
camera->disconnect();
fprintf(stderr, "captured=%d\n", captured);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(display, context);
eglDestroySurface(display, surface);
eglTerminate(display);
return captured ? 0 : 11;
}