2016-12-21 12 views
5

Pracuję nad aplikacją na iOS, która renderuje obrazy w OpenGL ES. Oto kod klucza fragment mojej funkcji do ustawiania parametrów tekstury i dane:Dlaczego funkcja glGenerateMipmap() na urządzeniu z systemem iOS zajmuje tyle pamięci klienckiej?

glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glPixelStorei(GL_PACK_ALIGNMENT, 4); 
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); 

Działa to dobrze na iPhone, z aliasingu kiedy powiększa się jednak. Więc starałem się używać mipmapa, modyfikując wcześniejsze kody w następujący sposób:

glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);// for mipmapping 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glPixelStorei(GL_PACK_ALIGNMENT, 4); 
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); 
glGenerateMipmap(GL_TEXTURE_2D);// This will generate all mip-mapping textures 

I to Mipmapping działa dobrze, nie więcej aliasingu podczas pomniejszania.

Uważam jednak, Mipmapping wziął zbyt dużo pamięci: nie pamięć grafiki, ale pamięć główna (pod względem OpenGL, a nie po stronie serwera pamięci, ale pamięć po stronie klienta)!

I potwierdził, że z monitora Memory Instrumentów:

Bez mipmappingu, mój konfigurowania funkcji tekstury ledwie spędza każdą kawałek pamięci, nawet jeśli źródłem jest tekstura rozdzielczości 4K obrazu. Taki wynik jasno dowodzi, że glTexImage2D alokuje pamięć tylko na serwerze OpenGL, tj. Kartę graficzną, dlatego nie może być monitorowany przez Monitor Pamięci, który nie dba o wykorzystanie pamięci graficznej.

Ale z mipmappingu wykorzystaniem glGenerateMipmap(), użycie pamięci sterty szybko wzrosła o około 100m gdy tworzę 4K tekstury. A po glDeleteTextures() wraca.

Wydaje się, że glGenerateMipmap() nie tylko generować MIP map tekstur w pamięci graficznej, ale także zużywają pamięci głównej. I ten kawałek pamięci głównej może zostać poddany recyklingowi po usunięciu tekstury. Bardzo dziwne, prawda?

Zastanawiam się dlaczego. A moim kluczowym punktem jest to, jak używać mapowania mip bez użycia zbyt dużej ilości pamięci? Dzięki za pomoc.

Odpowiedz

2

Godspeed.

  1. Być może trzeba będzie ustawić wartość GL_TEXTURE_MAX_LEVEL (domyślnie jest 1000) i GL_TEXTURE_BASE_LEVEL (wartość domyślna to 0).
  2. Obraz w rozdzielczości 4K nie oznacza "tekstury 4K". Z mojego doświadczenia wynika, że ​​jeśli długość obrazu wynosi 1025 X 1025, wówczas tekstura to 2048 X 2048. Proszę sprawdzić rozmiar obrazu.
  3. "pamięć procesora" -> "pamięć główna"; "pamięć gpu" -> "pamięć graficzna", ta ostatnia może być odpowiednia.
+0

1. Próbowałem dodanie glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3); ale nie ma znaczenia dla użycia pamięci. 2. Rozdzielczość obrazu to 6912 * 3456, więc najbliższa moc 2 rozmiarów to 8192 * 4096, tekstura RGBA8 zajmie 128 MB bajtów surowych. – godspeed1024

+0

@godspeed, patrz [mipmap encyklopedia] (https://en.wikipedia.org/wiki/Mipmap): „W przypadku obrazu RGB z trzech kanałów przechowywanych w oddzielnych płaszczyznach całkowita mipmapa można sobie wyobrazić jako okucie zgrabnie w kwadratowy obszar dwukrotnie większy od wymiarów oryginalnego obrazu z każdej strony, a także wizualnie pokazuje, jak używanie mipmap wymaga o 33% więcej pamięci. " –

+0

Jako wiki wartość GL_TEXTURE_MAX_LEVEL nie ma wpływu na rozmiar Mipmapa. –

1

Nie należy stosować glGenerateMipmap() zamiast użyć narzędzia takie jak PVRTexTools lub TextureTool i przy użyciu formatu kompresji PVRTC patrz: https://developer.apple.com/library/content/qa/qa1611/_index.html

+0

Dzięki. Wydaje się jednak, że takie podejście działa tylko w przypadku treści statycznych, na przykład tekstur modeli 3D w grze.Ale potrzebuję renderować dynamicznie załadowane obrazy. – godspeed1024

Powiązane problemy