ToolRotate - Android 화면 방향 회전의 근원
이 프로그램 은 안 드 로 이 드 플랫폼 의 OpenGL 라 이브 러 리 에 나타 난 bug 에서 비롯 되 었 습 니 다. 우리 의 보드 화면 해상 도 는 800 * 600 이 고 프로그램 이 세로 화면 상태 일 때 (600 * 800) 화면의 가로줄 에 톱날 이 나타 납 니 다.'설정' 과 같은 목록 이 있 는 프로그램 을 열 때 목록 사이 의 구분자 사이 에 양쪽 보다 아래로 픽 셀 이 잘못 되 어 있 는 것 을 볼 수 있 습 니 다.
Layer. cpp 의 mTextures 는 길이 가 2 인 Texture 배열 입 니 다. 두 Texture 의 데 이 터 는 사실 두 개의 Graphic Buffer 로 각각 앞 배경 buffer 를 대표 합 니 다.그 릴 때 OpenGL 을 사용 하여 프론트 데스크 톱 Texture 를 화면 에 렌 더 링 합 니 다.Texture 의 너비 가 각각 600 * 800 이면 화면 에 톱날 이 나타 납 니 다 (이것 은 Layer. cpp 의 onDraw 방법 에서 렌 더 링 할 Texture 의 width / height 값 을 인쇄 하여 확인 할 수 있 습 니 다).다른 사이즈 의 레이 어 는 아직 이 문 제 를 발견 하지 못 했다.예 를 들 어 제 판 위 에 상태 표시 줄 이라는 Layer 의 높이 는 25 이 고 입력 법 은 400 여 이 며 톱날 이 나타 나 지 않 았 습 니 다.
Texture 의 width / height 는 두 개의 int 32 일 뿐 입 니 다.t 속성.안에 있 는 Graphic Buffer 데 이 터 는 void * 포인터 일 뿐 픽 셀 데 이 터 를 저장 하 는 메모 리 를 가리 키 고 있 습 니 다.OpenGL 은 width / height 의 지도 에 따라 Graphic Buffer 의 데 이 터 를 화면 에 렌 더 링 한 것 이다.
만약 에 하나의 앱 이 중력 방향 에 따라 화면 을 회전한다 면 절 차 는 다음 과 같다. 시스템 은 센서 의 출력 데 이 터 를 계산 하고 회전 이 필요 할 때 Surfaceflinger 층 의 API 를 사용 하여 Surface 를 회전한다. 구체 적 인 방법 은 ToolRotate. cpp 의 소스 코드 를 볼 수 있다.클 라 이언 트 엔 드 의 Surface 는 서버 엔 드 의 Layer 에 대응 하기 때문에 Surface 를 바 꾸 는 방법 은 Layer 에서 mTextures 가 대표 하 는 두 Texture 의 너비 입 니 다.Surface 너비 가 바 뀌 면 이 Surface 위 에 그 려 진 View 트 리 가 알려 집 니 다. Surface 의 새로운 너비 에 따라 onMeasure, onLayout, onDraw 를 다시 시작 합 니 다.
2011.7.18
/ framework / base / opengl / libagl 은 opengles 의 기본 소프트 구현 코드 에 속 하고 컴 파일 된 라 이브 러 리 는 libGLES 입 니 다.android. so / framework / base / opengl / libs 디 렉 터 리 아래 세 개의 디 렉 터 리 가 있 습 니 다: GLESCM 과 GLES 2 는 각각 OpenGLES1. x 와 2.0 의 인터페이스 다.EGL 은 OpenGL 을 불 러 올 때 마 운 트 는 설정 에 따라 제조 업 체 의 구현 인지 libagl 의 기본 구현 인지 선택 합 니 다.다음 코드 는 / frameworks / base / opengl / libs / EGL / Loader. cpp 에서 발췌 합 니 다.
Loader::Loader()
{
char line[256];
char tag[256];
FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r");
if (cfg == NULL) {
// default config
LOGD("egl.cfg not found, using default config");
gConfig.add( entry_t(0, 0, "android") );
} else {
while (fgets(line, 256, cfg)) {
int dpy;
int impl;
if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) {
//LOGD(">>> %u %u %s", dpy, impl, tag);
gConfig.add( entry_t(dpy, impl, tag) );
}
}
fclose(cfg);
}
}
설정 파일 / system / lib / egl / egl. cfg 만 수정 하면 시스템 에 OpenGL 라 이브 러 리 를 맞 출 수 있 음 을 알 수 있 습 니 다.2011.7.19
/ system / lib / egl / egl. cfg 파일 의 내용 은 다음 과 같 습 니 다. 0, 0, android 0, 1, xxx 중 0 은 소프트 가 사용 하 는. so 라 이브 러 리 입 니 다.1. 억지로 사용 하 는. so 라 이브 러 리 를 대표 합 니 다.구체 적 으로 다음 코드 를 참고 할 수 있 습 니 다.
// get our driver loader
Loader& loader(Loader::getInstance());
// dynamically load all our EGL implementations for all displays
// and retrieve the corresponding EGLDisplay
// if that fails, don't use this driver.
// TODO: currently we only deal with EGL_DEFAULT_DISPLAY
egl_connection_t* cnx;
egl_display_t* d = &gDisplay[0];
cnx = &gEGLImpl[IMPL_SOFTWARE];
if (cnx->dso == 0) {
cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_SOFTWARE];
cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_SOFTWARE];
cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 0, cnx);
if (cnx->dso) {
EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
LOGE_IF(dpy==EGL_NO_DISPLAY, "No EGLDisplay for software EGL!");
d->disp[IMPL_SOFTWARE].dpy = dpy;
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx->dso);
cnx->dso = NULL;
}
}
}
cnx = &gEGLImpl[IMPL_HARDWARE];
if (cnx->dso == 0) {
char value[PROPERTY_VALUE_MAX];
property_get("debug.egl.hw", value, "1");
if (atoi(value) != 0) {
cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_HARDWARE];
cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_HARDWARE];
cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 1, cnx);
if (cnx->dso) {
EGLDisplay dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
LOGE_IF(dpy==EGL_NO_DISPLAY, "No EGLDisplay for hardware EGL!");
d->disp[IMPL_HARDWARE].dpy = dpy;
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx->dso);
cnx->dso = NULL;
}
}
} else {
LOGD("3D hardware acceleration is disabled");
}
}
if (!gEGLImpl[IMPL_SOFTWARE].dso && !gEGLImpl[IMPL_HARDWARE].dso) {
return EGL_FALSE;
}
return EGL_TRUE;
소프트 구현 라 이브 러 리 와 하드웨어 구현 라 이브 러 리 는 각각 gEGLImpl [IMPL SOFTWARE], gEGLImpl [IMPL HARDWARE] 에 넣 습 니 다.2011.7.20
. so 라 이브 러 리 를 불 러 오 는 loader. open () 함 수 를 더 깊이 살 펴 보 세 요.이것 은 그것 의 핵심 코드 입 니 다.
dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2);
if (dso) {
hnd = new driver_t(dso);
} else {
// Always load EGL first
dso = load_driver("EGL", tag, cnx, EGL);
if (dso) {
hnd = new driver_t(dso);
// TODO: make this more automated
hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM );
hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
}
}
libGLES 불 러 오기tag. so, 불 러 오 는 데 성공 하지 못 하면 세 개의 라 이브 러 리 를 순서대로 불 러 옵 니 다: libEGLxxx.so,libGLESv1_CM.so,libGLESv2.so。로 딩 라 이브 러 리 는 모두 사용 하 는 loaddriver 함수.이 함 수 는 / system / lib / egl / 디 렉 터 리 에서 불 러 올 라 이브 러 리 를 찾 은 다음 eglnames 와 glnames 두 배열 의 이름 목록 은 라 이브 러 리 에서 해당 함 수 를 검색 하고 검색 한 함수 지침 을 저장 합 니 다.
egl 의 함수 포인터 가 cnc - > egl 에 저 장 됩 니 다.GLESv 1 의 포인터 가 cnc - > hooks [GLESv 1 INDEX] - > gl 에 저 장 됩 니 다.GLESv 2 포인터 가 cnc - > hooks [GLESv 2 INDEX] - > gl 에 저 장 됩 니 다.
재 미 있 는 곳 이 하나 있 는데, 바로 eglnames,gl_names, cnx - > egl, cnx - > hooks [GLESv 1 INDEX] - > gl, cnx - > hooks [GLESv 2 INDEX] - > gl 이 몇 개의 구조 체 에 대한 정의:
#undef GL_ENTRY
#undef EGL_ENTRY
#define GL_ENTRY(_r, _api, ...) #_api,
#define EGL_ENTRY(_r, _api, ...) #_api,
char const * const gl_names[] = {
#include "entries.in"
NULL
};
char const * const egl_names[] = {
#include "egl_entries.in"
NULL
};
#undef GL_ENTRY
#undef EGL_ENTRY
#undef GL_ENTRY
#undef EGL_ENTRY
#define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
#define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
struct egl_t {
#include "EGL/egl_entries.in"
};
struct gl_hooks_t {
struct gl_t {
#include "entries.in"
} gl;
struct gl_ext_t {
__eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];
} ext;
};
#undef GL_ENTRY
#undef EGL_ENTRY
먼저 매크로 를 정의 한 다음 함수 이름 을 매크로 형식 으로 파일 에 기록 합 니 다.그리고 코드 에 파일 을 포함 하고 마지막 으로 컴 파일 할 때 펼 칩 니 다.유연성 이 뛰어나다.
libagl 디 렉 터 리 는 OpenGLES 의 기본 소프트 구현 입 니 다.lib/GLES_CM 과 lib / GLES 2 두 디 렉 터 리 는 각각 1. x 와 2.0 의 실현 으로 모두 libagl 안의 실현 을 호출 했다.lib / EGL 디 렉 터 리 에 라 이브 러 리 함수 로 불 러 옵 니 다.만약 에 제 가 ABC 회사 라 고 가정 하면 저 는 libagl 라 이브 러 리 를 사용 하지 않 고 자신의 OpenGLES 를 실현 하여 자신의 하드웨어 가속 화 를 사 용 했 습 니 다.그럼 제 라 이브 러 리 는 libGLESv 1 입 니 다.CM_ABC.so,libGLESv2_ABC. so, 일부 OpenGLES 함수 가 시스템 구현 (소프트 구현) 을 이용 하려 면 설정 파일 을 이렇게 쓰 십시오.
0,0,android
0,1,ABC
내 자신의 실현 을 완전히 이용 하면 이렇게 쓴다.
0,1,ABC
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.