2012-12-27 31 views
15

Pracuję dla Androida, używając opengl/egl. Moja aplikacja wymaga drugiego kontekstu do ładowania tekstur z drugiego wątku.Dlaczego metoda eglMakeCurrent() kończy się niepowodzeniem z EGL_BAD_MATCH?

Mój kod działa poprawnie na Androidzie 2.3, ale kiedy próbuję kod na urządzeniu androidowym lub emulatorze 4.0.3, eglMakeCurrent() kończy się niepowodzeniem z EGL_BAD_MATCH.

Inicjowanie drugiego kontekstu i jego bufora pikseli działa również dobrze, więc nie jestem pewien, od czego zacząć szukanie tego błędu.

Jest to kod inicjalizacji:

ANativeWindow *window = (ANativeWindow*)displaySurface; 

EGLint dummy, format; 

display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 

eglInitialize(display, 0, 0); 

EGLint contextAttribs[] = 
{ 
    EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE 
}; 

const EGLint configAttribs[] = 
{ 
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
    EGL_BLUE_SIZE, 8, 
    EGL_GREEN_SIZE, 8, 
    EGL_RED_SIZE, 8, 
    EGL_ALPHA_SIZE, 8, 
    EGL_BUFFER_SIZE, 32, 
    EGL_DEPTH_SIZE, 24, 
    EGL_NONE 
}; 

EGLint numConfigs; 
EGLConfig config; 

eglChooseConfig(display, configAttribs, &config, 1, &numConfigs); 
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); 
ANativeWindow_setBuffersGeometry(window, 0, 0, format); 

surface = eglCreateWindowSurface(display, config, window, NULL); 
if(surface == NULL) 
    Trace("error creating window surface: " + GetEglError()); 

context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); 
if(context == NULL) 
    Trace("error creating main context: " + GetEglError()); 

const EGLint auxConfigAttribs[] = 
{ 
    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 
    EGL_BLUE_SIZE, 8, 
    EGL_GREEN_SIZE, 8, 
    EGL_RED_SIZE, 8, 
    EGL_ALPHA_SIZE, 8, 
    EGL_DEPTH_SIZE, 0, 
    EGL_STENCIL_SIZE, 0, 
    EGL_NONE 
}; 

EGLint pbufferAttribs[] = 
{ 
    EGL_WIDTH, 1, 
    EGL_HEIGHT, 1, 
    EGL_TEXTURE_TARGET, EGL_NO_TEXTURE, 
    EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE, 
    EGL_NONE 
}; 

EGLint auxNumConfigs; 
EGLConfig auxConfig; 

eglChooseConfig(display, auxConfigAttribs, &auxConfig, 1, &auxNumConfigs); 

auxSurface = eglCreatePbufferSurface(display, auxConfig, pbufferAttribs); 
if(auxSurface == NULL) 
    Trace("error creating pbuffer surface: " + GetEglError()); 

auxContext = eglCreateContext(display, auxConfig, context, contextAttribs); 
if(auxSurface == NULL) 
    Trace("error creating auxilliary context: " + GetEglError()); 

if(!eglMakeCurrent(display, surface, surface, context)) 
    Trace("could not make main context current: " + GetEglError()); 

Na moim Android 2.3 urządzenie (HTC Desire), powyższy kod inicjalizacji działa idealnie i mogę zrobić prąd auxContext, a tekstury obciążenia dobrze.

ALE, na moim urządzeniu z Androidem 4.0.3 (Samsung Nexus S) i moim urządzeniu z Androidem 4.1 (Galaxy Note 2) eglMakeCurrent() kończy się niepowodzeniem z EGL_BAD_MATCH po pomyślnym zainicjowaniu.

Czy ktoś wie, dlaczego mogę uzyskać ten błąd?

+1

zauważyłem, że mam EGL_BAD_MATCH Dzwoniąc eglMakeCurrent z Galaxy S2 czasami. Sądzę, że zawęziłem warunki błędu do a) tworząc kontekst na innym wątku, niż jest on tworzony, lub b) czyniąc kontekst bieżącym na drugim wątku bez ~ zwalniania go z pierwszego wątku. – nmr

+0

zobacz komentarze zaznaczonej odpowiedzi dla rozwiązania – bitwise

Odpowiedz

11

Ah, coś o czym naprawdę wiem. ;) [Spędziłem najlepszą część 5 lat pracując nad różnymi implementacjami EGL].

Jestem prawie pewien, że Twój surface jest innym formatem niż faktyczna powierzchnia wyświetlania. Nie jestem do końca pewien, CO MOGŁA BYĆ różnica, ani tego, co należy zmienić. Być może EGL_DEPTH_SIZE? Możesz spróbować wyliczyć dostępne tryby i sprawdzić, czy jakikolwiek wygląd jest "prawdopodobny". Wiem, to trochę uciążliwe, ale robiłem to kilka razy w przeszłości - z tą różnicą, że zazwyczaj mogłem przejrzeć kod źródłowy EGL i dowiedzieć się, co zrobiłem źle ... ;)

+0

Chodzi o to, że makeCurrent() działa dobrze dla głównego kontekstu na wszystkich telefonach, ale nie dla drugiego/wspólnego kontekstu na pozostałych dwóch telefonach. Jednak znalazłem post, który sugeruje coś takiego, co mówisz: http://stackoverflow.com/questions/7523597/egl-bad-match-with-droid-droid-2 - Być może wracam do innej konfiguracji niż to, o co proszę ** powierzchni **, ale potem tworzenie bufora pikseli z ** żądaną ** konfiguracją zamiast ** zwróconej ** konfiguracji, która może być przyczyną dopasowania partii. – bitwise

+1

Tak, jest całkiem możliwe, że konfiguracja działa na jednym, dwóch, pięciu lub 16 telefonach, ale kończy się niepowodzeniem na jednym lub dwóch innych. Byłem w pewnym momencie odpowiedzialny za testowanie sterownika EGL dla konkretnego modelu sprzętu, który korzystał z innego zestawu konfiguracji EGL niż inny sprzęt, który mieliśmy do dyspozycji. Tak więc, gdy tylko nowy test został wprowadzony do zestawu testów, prawie na pewno włamał się do mojego sprzętu, ale pracował nad wszystkimi innymi. Potem pojawiło się wyzwanie znalezienia "dobrego kompromisu" dla tego, co działało na wszystkich platformach - lub dodania jakiegoś kodu do radzenia sobie z "Jeśli mamy HW X, rób to, to jeszcze rób". –

+6

Próbowałem wyliczyć wszystkie konfiguracje, które doprowadziły do ​​dwóch odkryć. Po pierwsze, prawie każda konfiguracja wyświetlania obsługująca EGL_WINDOW_BIT obsługiwała również EGL_PBUFFER_BIT, co czyni całkowicie bezcelowe tworzenie dwóch oddzielnych konfiguracji. Po drugie, eglChooseConfig nie wydaje się działać poprawnie na wszystkich urządzeniach/wersjach Androida. Mogło to być zgodne z projektem, tak jak miało to miejsce na jednym z emulatorów bez obsługi GPU, ale konfiguracja, którą otrzymywałem, nie spełniała nawet specyfikacji, którą wprowadziłem. Napisałem więc własny eglChooseConfig i użyłem tej samej konfiguracji dla obie powierzchnie, a teraz wszystko działa. – bitwise

5

Jeśli otrzymujesz ten błąd, ale nie radzisz sobie z tą powierzchnią lub teksturami, idź, aby uruchomić i wpisz .android przejdź do AVD, a twój aktualny Emulator usuń plik daty użytkownika z pliku .img, uruchom ponownie emulator, a następnie przetestuj. Działa to dla mnie, jeśli dzieje się to podczas testowania urządzenia, wyczyść dane i uruchom ponownie aplikację. Pozdrawiam tych, którzy uważają to za pomocne.

+0

to pytanie zostało oznaczone odpowiedzi prawie 2 lata temu .. – bitwise

+13

tak, wiem, ale z jakiegoś powodu ten błąd się zdarzyć i zaakceptowana odpowiedź nie była pomocna w moim przypadku. Następnie rozwiązałem go i opublikowałem tutaj. Więc jeśli ktoś wpadnie na taki błąd, może się przydać. – ralphgabb

-2
int config_attrs[] = 
    { 
     EGL_RED_SIZE, 8, 

EGL_GREEN_SIZE, 8, 

     EGL_BLUE_SIZE, 8, 

     EGL_ALPHA_SIZE, 8, 

     EGL_BUFFER_SIZE, 16, 

     EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 

     EGL_DEPTH_SIZE, 16, 

     EGL_STENCIL_SIZE, 8, 

     EGL_SAMPLE_BUFFERS, 0, 

     EGL_SAMPLES, 0, 
#ifdef _IRR_COMPILE_WITH_OGLES1_  
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, 
#else 
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
#endif 
     EGL_NONE, 0 
    }; 

    int context_attrs[] = 
    { 
#ifdef _IRR_COMPILE_WITH_OGLES1_   
     EGL_CONTEXT_CLIENT_VERSION, 1, 
#else 
     EGL_CONTEXT_CLIENT_VERSION, 2, 
#endif 
     EGL_NONE, 0 
    }; 

///// 
//ogles1 and ogles2 use different libEGL.dll, make sure 

s_egl_display = eglGetDisplay (g_hDC); 

    if (s_egl_display == EGL_NO_DISPLAY) 
    { 
     return; 
    } 

    if (!eglInitialize (s_egl_display, &major, &minor)) 
    { 
     return; 
    } 

    if (!eglChooseConfig (s_egl_display, config_attrs, &g_egl_config, 1, &configs) || (configs != 1)) 
    { 
     return; 
    } 

    s_egl_surface = eglCreateWindowSurface (s_egl_display, g_egl_config, g_hWnd, 0); 
    if (eglGetError() != EGL_SUCCESS) 
    { 
     return; 
    } 

    eRet = eglBindAPI(EGL_OPENGL_ES_API); 

    s_egl_context = eglCreateContext (s_egl_display, g_egl_config, EGL_NO_CONTEXT, context_attrs); 
    if (eglGetError() != EGL_SUCCESS) 
    { 
     return; 
    } 

    eglMakeCurrent (s_egl_display, s_egl_surface, s_egl_surface, s_egl_context); 
    if (eglGetError() != EGL_SUCCESS) 
    { 
     return; 
    } 
+1

Proszę oświecić nas kilkoma słowami. –

Powiązane problemy