2012-07-11 6 views
2

Google 제품에는 화면 전체를 빠르게 복사해야하는 풀 프레임 픽셀 데이터를 기본적으로 생성하는 소프트웨어 이미지 디코더가 포함되어 있습니다 (우리는 iOS에서 실행 중입니다).iOS에서 RGB 픽셀 데이터를 고성능으로 복사

현재 우리는 CGBitmapContextCreate를 사용하고 있으며 메모리 버퍼에 직접 액세스 한 다음 각 프레임마다 CGBitmapContextCreateImage를 호출 한 다음 해당 비트 맵을 화면에 그립니다. 괜찮은 프레임 속도에서 iPad의 망막 디스플레이에서 전체 화면 새로 고침이 너무 느립니다 (그러나 Retina가 아닌 장치에서는 괜찮습니다).

우리는 glTexImage2D 및 glTexSubImage2D (본질적으로 텍스처로 렌더링)의 사용을 포함하여 모든 종류의 OpenGL ES 기반 접근법을 시도했지만 CPU 사용량은 여전히 ​​높으며 ~ 30FPS 이상을 얻을 수 없습니다 문제는 30 FPS를 사용하면 픽셀을 화면에 복사하기위한 CPU 사용량이 거의 100 %에 불과하다는 것입니다. 즉, 픽셀을 화면에 복사 할 때 CPU 사용량이 거의 100 %에 달합니다. CPU.

최대 성능을 제공하는 OpenGL 또는 iOS API를 사용할 수 있습니다. 픽셀 데이터는 픽셀 당 32 비트 RGBA 데이터로 포맷되지만 여기에는 약간의 융통성이 있습니다 ...

어떤 제안이 있습니까?

+0

계측기를 사용하여 정확히 어떤 작업이 모든 CPU를 사용하는지 확인 했습니까? 나는 비슷한 것을했는데 많은 시간을 RGBA를 ARGB로 변환하는 데 지출했다는 것을 발견했다. (당신이 아직하지 않았다면 당신의 문제는 아니지만 프로파일을 보는 것이 도움이 될 것이다.) – nielsbot

+0

"비트 맵을 화면 "의미? 당신은 UIView의'-drawRect :'메소드를 드로잉하거나 레이어에 CGImage를 두거나 UIImageView를 사용하고 있습니까? 후자의 두 메소드는 상당히 빨라야합니다.이 [이전 응답] (http://stackoverflow.com/questions/10410106/drawing-image-with-coregraphics-on-retina-ipad-is-slow/10424635#10424635)을 참조하십시오.). –

+0

"glTexSubImage2D"접근 방식은 무엇입니까? 나는 이것이 제대로 완료되면 충분히 빠르다고 생각합니다. 당신이하는 일을 이해하는 방법은 CPU에서 미가공 픽셀 데이터를 처리하고 그 데이터를 GPU에 푸시하고 렌더링하는 것입니다. 최대 4kx4kx4B (64MB)의 데이터가 전체 텍스처 (iPad3)에 대해 푸시되고 너무 많이 보이지 않습니다. 어쨌든, 어떤 경우이든 이것이 fps의 하락을 유발하는 것이라면, 나는 보이지 않습니다. 더 나은 방법은 다음 픽셀과 함께 GPU를 직접 작업. –

답변

0

그런 다음 pbuffer 또는 FBO를 OpenGL ES에 의한 추가 렌더링을위한 텍스처 맵으로 사용할 수 있습니다. 이것을 Render to Texture 또는 RTT라고합니다. EGL에서 훨씬 빠른 검색 pbuffer 또는 FBO

+0

Render to Texture는이 문제를 어떻게 해결할 것입니까? CPU에서 기존 비트를 가져 와서 화면으로 가져 오려고합니다. 우리의 렌더링은 GPU가 아니라 CPU에 의해 수행됩니다. – ldoogy

+0

UIImage는 IOS에있는 CPU에서 가장 빠릅니다. –

+0

@talktomevintron - 아니, 가장 확실한 것은 아닙니다. 벤치 마크에서 UIImage의 원시 픽셀 데이터를 추출하는 데 중요한 Core Graphics 오버 헤드가 있습니다. 일부 다른 형식의 원시 픽셀 데이터로 작업하는 것이 훨씬 낫습니다. –

2

그래서 나쁜 소식은 당신이 정말로 어려운 문제에 부딪쳤다는 것입니다. 저는이 특정 영역에서 많은 연구를 해왔고 현재는 전체 화면의 크기 인 프레임 버퍼를 실제로 2x로 블리트 할 수있는 유일한 방법은 h.264 디코더를 사용하는 것입니다. 이미지 메모리가 이미 실제 메모리로 디코딩 된 후에는 OpenGL을 사용하여 할 수있는 좋은 트릭이 꽤 있습니다 (GPUImage를 살펴보십시오). 그러나 큰 문제는 픽셀을 라이브 메모리에서 화면으로 이동하는 방법이 아니라는 것입니다. 진짜 문제는 픽셀을 인코딩 된 형식에서 실제 메모리로 이동하는 방법입니다. 파일 매핑 된 메모리를 사용하여 디스크의 픽셀을 유지할 수 있지만 IO 하위 시스템은 매핑 된 메모리에서 2x 전체 화면 크기의 이미지를 스트리밍 할 수 있도록 충분한 페이지를 스왑 할 수 없을 정도로 빠릅니다. 이것은 1x 전체 화면 크기로 잘 작동하는 데 사용되었지만 이제 2x 크기 화면은 실제 메모리 크기의 4 배이고 하드웨어는 계속 유지할 수 없습니다. 프레임을 PNG와 같이 압축 된 형식으로 디스크에 저장할 수도 있습니다. 그러나 압축 된 형식을 디코딩하면 IO 바인딩에서 CPU 바인딩으로 문제가 변경되며 여전히 문제가 있습니다. 이 방법으로 찾은 전체 소스 코드와 타이밍 결과는 내 블로그 게시물 opengl_write_texture_cache을 참조하십시오. 입력 이미지 데이터를 (8 비트 테이블처럼) 제한 할 수있는 매우 특정한 형식을 가지고 있다면,이 예제처럼 xcode 프로젝트 opengl_color_cycle과 같이 GPU를 사용하여 8 비트 데이터를 셰이더를 통해 32BPP 픽셀로 블 리팅 할 수 있습니다 . 하지만 실제로 하드웨어에서 많은 양의 데이터를 디코딩 할 수 있기 때문에 h.264 디코더를 어떻게 사용할 수 있는지 살펴 보는 것이 좋습니다. 다른 방법으로는 원하는 결과를 얻을 수 없습니다.

0

몇 년 후 여러 상황이 발생하여 iOS 용 기본 'pixel viewer'보기를 구현하기로 결정했습니다. 32-bpp RGBA, 24-bpp RGB 및 여러 YpCbCr 형식을 포함하여 다양한 형식으로 픽셀 버퍼의 고도로 최적화 된 디스플레이를 지원합니다. 또한 스마트 스케일링 대한 UIViewContentMode *를 모두 지원

, 스케일 등

코드 높게 (OpenGL을 사용) 최적화를/충전 맞 및 아이폰 심지어 이전 iOS 기기에서 뛰어난 성능을 달성 할 5 또는 원래 iPad Air.이러한 장치의 경우 24bpp 형식을 제외한 모든 픽셀 형식에서 60FPS를 달성합니다.이 형식에서는 약 30-50fps (일반적으로 장치의 기본 해상도에서 픽셀 버퍼를 표시하여 벤치 마크를 수행하므로 iPad는 iPhone보다 훨씬 많은 픽셀을 밀어 넣어야합니다. 5).

EEPixelViewer을 확인하십시오.

1

CoreVideo가 가장 보편적 인 프레임 워크입니다. OpenGL 및 CoreGraphics 접근 방식을 사용하면 비트 맵 데이터를 주 메모리에서 GPU 메모리로 이동하는 비용이 많이 들게됩니다. 이 비용은 데스크톱에도 있지만, 특히 iPhone에는 상당히 고통 스럽습니다.

이 경우 병목 현상이 텍스처 데이터 복사본이므로 OpenGL에서 CoreGraphics보다 속도를 크게 향상시키지 않습니다. OpenGL은 렌더링 파이프 라인을보다 효율적으로 만들지 만 손상은 이미 텍스처 복사본에 의해 완료되었습니다.

그래서 CoreVideo가 최선의 방법입니다. 프레임 워크를 이해함에 따라, 발생하는 바로 그 문제를 해결할 수 있습니다.

관련 문제