2010-11-04 36 views
10

Tôi đang làm việc trên một ứng dụng iPhone là OpenGL ES và giao diện người dùng iPhone thông thường. Điều này có nghĩa là có một EAGLView chào người dùng, sau đó một số thông thường UIView s được đẩy lên trên đó (có một UINavigationController làm bộ điều khiển gốc).Tai nạn ngẫu nhiên trên ứng dụng OpenGL của iPhone khi điều hướng

Tôi gặp sự cố ngẫu nhiên (nhưng rất thường xuyên) khi điều hướng trở lại từ một chế độ xem phụ. Đây là dấu vết ngăn xếp (... bị kiểm duyệt ...), từ bản dựng Bản phát hành, nhưng nó chỉ bị lỗi trong Debug.

#0 0x006863d0 in GetFBOBuffers() 
#1 0x00660120 in TerminateScene() 
#2 0x00660314 in FlushScene() 
#3 0x00660cd4 in FlushHW() 
#4 0x0066a6a0 in GLESPresentView() 
#5 0x323533a4 in -[EAGLContext presentRenderbuffer:]() 
#6 0x000026c0 in -[EAGLView presentFramebuffer] (self=0x11ce60, _cmd=<value temporarily unavailable, due to optimizations>) at (...)/Classes/EAGLView.m:157 
#7 0x00004fdc in -[(...)ViewController drawFrame] (self=<value temporarily unavailable, due to optimizations>, _cmd=<value temporarily unavailable, due to optimizations>) at (...) ViewController.m:380 
#8 0x336ebd9a in __NSFireTimer() 
#9 0x323f54c2 in CFRunLoopRunSpecific() 
#10 0x323f4c1e in CFRunLoopRunInMode() 
#11 0x335051c8 in GSEventRunModal() 
#12 0x324a6c30 in -[UIApplication _run]() 
#13 0x324a5230 in UIApplicationMain() 
#14 0x0000214c in main (argc=1, argv=0x2ffff568) at (...)/main.m:14 

Dưới đây là danh sách những điều tôi biết:

  • Ứng dụng của tôi không nhận được một cảnh báo bộ nhớ.
  • Ứng dụng của tôi không có rò rỉ được xác định trong Công cụ.
  • Không có sự cố trên Trình mô phỏng, nhưng đôi khi độ trễ rất đáng chú ý.
  • Có một lượng đáng kể dữ liệu được phát hành trong Instruments/OpenGL/ResourceBytes ngay trước khi xảy ra sự cố.
  • Tôi đang sử dụng cả hai mảng VBO và vertex/texcoord/normals.

Vì vậy, tôi biết đó phải là một số loại dữ liệu được phát hành hoặc bị hủy, nhưng tôi không biết cách tìm kiếm. Bất cứ lời khuyên và thủ thuật sẽ được đánh giá ;-)

UPDATE:

Sau khi thiết lập một số breakpoint, di chuyển dọc theo chồng, đâm vào các biến khác nhau, tôi đã tìm thấy lý do của sự sụp đổ, nhưng chưa nguồn.

Trong EAGLView, trong phương thức presentFramebuffer ở đâu và khi xảy ra sự cố, colorRenderBuffer ivar là 0 nếu tôi có thể tin gdb, mặc dù cố gắng phá vỡ khi nào 0 dường như không hoạt động.

Dường như cuộc gọi deleteFrameBuffer từ layoutSubviews không khớp với số createFramebuffer.

UPDATE 2:

Rất nhiều breakpoint sau ... Tôi đã tìm thấy một tình huống sai: [EAGLView layoutSubviews] được gọi ở giữa một drawFrame! Vì vậy, các bộ đệm bị xóa trong khi sử dụng ... BAM!

Bây giờ, làm cách nào để khắc phục rằng?

+0

Có vẻ như bạn đang giải phóng một thứ gì đó ... –

+0

Vâng, tôi không tự giải phóng bất cứ điều gì. Chế độ xem bị đẩy lên chế độ xem OpenGL của tôi, sau đó xuất hiện, sau đó nó gặp sự cố trong vài lần hiển thị đầu tiên. – jv42

+0

Tôi muốn có một sửa chữa thực sự cho điều đó, nó sẽ cho tôi một sự hiểu biết tốt hơn về tương tác UIKit vs OpenGL ES. Đã thêm tiền thưởng. – jv42

Trả lời

3

Tôi chưa tìm thấy bản sửa lỗi 'thích hợp', nhưng tôi đã thêm một giải pháp thay thế.

Trong presentFramebuffer, tôi đặt một boolean quanh rendering:

if (context) 
{ 
    isRendering_PATCH_VARIABLE = YES; 

    [EAGLContext setCurrentContext:context]; 

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 

    success = [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0); 

    isRendering_PATCH_VARIABLE = NO; 
} 

và trong deleteFramebuffer, tôi kiểm tra boolean này:

if (isRendering_PATCH_VARIABLE) 
{ 
    NSLog(@"GOTCHA - CRASH AVOIDED"); 
} 

if (context && !isRendering_PATCH_VARIABLE) 
{ 
    // ... 
} 

Nó dường như không có tác dụng phụ (như màn hình bị hỏng, vv), vì vậy tôi sẽ để nó như thế cho thời điểm này.

1

Một đâm trong bóng tối: Thiết bị của bạn bị thiếu bộ nhớ, ứng dụng nhận cảnh báo bộ nhớ và bộ điều khiển chịu trách nhiệm cho chế độ xem GL phát hành chế độ xem, đó là thứ bạn không đếm? Vấn đề có biến mất khi bạn chặn mặc định didReceiveMemoryWarning không?

- (void) didReceiveMemoryWarning { /* nothing we can do, sorry */ } 

… hoặc có thể bạn đang gọi OpenGL từ chuỗi khác không có ngữ cảnh?

+0

Không phải cảnh báo bộ nhớ. Tôi không sử dụng nhiều bộ nhớ (~ 5-6 MB) và tôi đã xác minh điều đó. – jv42

+0

Tôi cũng không tạo bất kỳ chủ đề nào và bối cảnh của tôi là hợp lệ trong gdb. – jv42

+0

FYI - thêm hỗ trợ đa màn hình cho một ứng dụng iOS hiện đại, tôi đã có chính xác điều này.Bộ nhớ "thêm" cần thiết cho đa màn hình là rất lớn (tất cả những gì tôi đang làm là tạo một EAGLContext và hiển thị nó), và nó đẩy ứng dụng lên giới hạn mem, và iOS không cung cấp đủ mem cho khung nhìn thứ hai để render . Chế độ xem chính bị treo, lỗi ứng dụng và Apple ghi lại nội dung về GPU đã bị lỗi (không - iOS hết bộ nhớ và từ chối phân bổ mem) – Adam

3

Đây là phỏng đoán tự nhiên dựa trên điều tôi đã làm gần đây.

Điều tôi đã làm là phá vỡ giai đoạn tải. Tôi muốn hiển thị thanh tiến trình khi tôi tải lên một số tài nguyên - đó là một quá trình chậm nên tôi muốn cung cấp một số phản hồi của người dùng.

Bước đầu tiên của tôi tương tự như ví dụ OpenGL ES được cung cấp cùng với Xcode mà tôi gọi là init trên ES? Renderer. Nhưng sau đó tôi đã ngừng quá trình để tôi có thể tải các tài nguyên khác.

Để cắt một câu chuyện dài, vì sắp xếp lại mã của tôi, [EAGLView layoutSubviews] chưa bao giờ được gọi sau khi khởi tạo. Tôi đã không nhận được một vụ tai nạn, nhưng không có gì nhiều xảy ra sau thời điểm này.

Điều tôi phải làm là sau khi hoàn thành việc khởi tạo ngữ cảnh của OpenGL và tải tất cả dữ liệu của mình, tôi phải gọi thủ công [EAGLView layoutSubviews]. Điều này dường như sửa chữa mọi thứ cho tôi.

Có thể bạn cần thử một cái gì đó tương tự. Sau khi bạn khởi tạo bối cảnh và dữ liệu OpenGL của mình, hãy gọi số [EAGLView layoutSubviews] trước khi bạn thực hiện các thao tác vẽ của mình. Có thể điều này sẽ ngừng cuộc gọi này lại xuất hiện lại trong bước hiển thị của bạn và bị lỗi.

+0

Thú vị, cảm ơn. Tôi sẽ cố gắng làm điều đó. – jv42

1

Tôi gặp sự cố này và đã sử dụng công việc của bạn trong một thời gian. Tuy nhiên, những gì tôi vừa mới nhận thấy là vụ tai nạn chỉ xảy ra trên một sự thay đổi định hướng.

Tôi đã thay đổi bộ điều khiển chế độ xem gốc để tạm dừng liên kết hiển thị trong WillRotate ... và tiếp tục lại trong các hàm đại biểu DidRotateFrom ....

Điều này đã khắc phục được sự cố và tôi không cần công việc hack xung quanh nữa.

Rất tiếc, có vẻ như sự cố của bạn hơi khác một chút nhưng tôi nghĩ rằng tôi chỉ nên đăng bài này trong trường hợp.

+0

Thú vị! Tôi không còn làm việc trên dự án đó, đó là một PoC nhanh chóng, nhưng tôi sẽ giữ cho giải pháp của bạn trong tâm trí. – jv42

Các vấn đề liên quan