Release Vulpes OS 2.7-preview.24
This commit is contained in:
parent
49572b6b45
commit
97ef99f827
135 changed files with 7717 additions and 2524 deletions
175
tundra/probes/beatles-camera-glconsumer-probe.cpp
Normal file
175
tundra/probes/beatles-camera-glconsumer-probe.cpp
Normal 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;
|
||||
}
|
||||
Loading…
Reference in a new issue