2015-09-02 18 views
6

Tôi đang cố gắng hiển thị HUD qua ứng dụng OpenGL ES 2.0 được viết bằng C trên nền tảng ARM Linux.OpenGL ES 2.0 + Cairo: HUD

Tôi hiện đang sử dụng 2 hình tam giác được đặt gần mặt cắt cắt gần và ốp lát kết cấu lên chúng. Các kết cấu là kích thước của màn hình và chủ yếu là minh bạch, ngoại trừ các phần mà tôi có văn bản trả lại. Các kết cấu được tạo ra bằng cách sử dụng Pango/Cairo

Nếu tôi bật HUD (bỏ ghi chú gọi hàm render_ui), tôi hiện đang đạt hiệu suất 50% (Đi từ 60fps đến 30fps).

Đây là đoạn mã để làm cho HUD:

void render_ui(OGL_STATE_T *state) { 

    glUseProgram(state->uiHandle); 

    matIdentity(modelViewMatrix); 
    matTranslate(modelViewMatrix, 0, 0, -0.51); 

    const GLfloat *mvMat2 = modelViewMatrix; 

    glViewport(0,0,state->screen_width, state->screen_height); 

    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_BLEND); 

    glBindBuffer(GL_ARRAY_BUFFER, state->uiVB); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state->uiIB); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, state->uiTex); 
    glUniform1i(_uiTexUniform, 0); 

    glUniformMatrix4fv(_uiProjectionUniform, 1, 0, pMat); 
    glUniformMatrix4fv(_uiModelViewUniform, 1, 0, mvMat2); 

    glVertexAttribPointer(_uiPositionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
    glVertexAttribPointer(_uiColorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 
      (GLvoid *) (sizeof(GLfloat) * 3)); 
    glVertexAttribPointer(_uiTexCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), 
      (GLvoid *) (sizeof(GLfloat) * 7)); 

    glEnableVertexAttribArray(_uiPositionSlot); 
    glEnableVertexAttribArray(_uiColorSlot); 
    glEnableVertexAttribArray(_uiTexCoordSlot); 

    glDrawElements(GL_TRIANGLES, uiIndicesArraySize/uiIndicesElementSize, 
      GL_UNSIGNED_BYTE, 0); 

    glDisableVertexAttribArray(_uiTexCoordSlot); 
    glDisable(GL_BLEND); 

    GLenum err; 

    if ((err = glGetError()) != GL_NO_ERROR) 
     printf("There was an error"); 
} 

Cần phải có một cách hợp lý hơn để làm điều này.

+0

GPU trên nền tảng của bạn (PowerVr, Adreno, Mali, Nvidia Tegra ...) là gì? Ngoài ra độ phân giải là gì? –

+0

@VB_overflow Vivante GPU/bo mạch Freescale iMX6. Độ phân giải là 1920x1080. – ReX357

Trả lời

3

Trên các thiết bị di động GPU rất nhạy cảm với pha trộn, điều này cho nhiều lý do:

  • Trộn tiêu thụ băng thông hơn (cần phải đọc pixel hiện để pha trộn nó với cái mới)
  • Trộn có thể phá vỡ bề mặt ẩn loại bỏ tối ưu hóa
  • Blending cũng có thể phá vỡ ngói dựa defered render tối ưu hóa

Vì vậy, trong ngắn GPU di động tình yêu các đa giác đục và ghét các hình trong suốt.

Lưu ý rằng tổng diện tích đất bị chiếm đóng bởi đa giác trong suốt trên màn hình cũng rất quan trọng do "gạch dựa trên" bản chất của hầu hết các GPU di động (khi một ngói/bin được bao phủ bởi đa giác trong suốt, bạn có thể mất một số tối ưu GPU cho nó). Ngoài ra, vì bạn nói rằng bạn giảm mạnh từ 60fps xuống 30fps, tôi sẽ kết luận rằng GPU thiết bị đang chặn, chờ cho đồng bộ hóa dọc 60Hz màn hình hoán đổi, vì vậy điều này có nghĩa là khung DT của bạn chỉ có thể là bội số 16ms, do đó, bạn có thể chỉ có thể nhận được các giá trị fps như: 60, 30, 15, 7.5, ...

Vì vậy, nếu bạn ở 60 hình/giây, nhưng hãy thêm thứ gì đó vào vòng lặp chính của ứng dụng sẽ giảm lý thuyết fps đến 57fps, sau đó do chờ đợi đồng bộ hóa dọc, bạn sẽ đột ngột truy cập 30 khung hình/giây. VSync có thể bị vô hiệu hóa, hoặc các kỹ thuật như bộ đệm ba lần có thể được sử dụng để giảm thiểu điều này, nhưng với OpenGLES cách thực hiện điều này là cụ thể đối với phần cứng OS & bạn đang làm việc ... không có cách chính thức để thực hiện nó trên tất cả các thiết bị ".

Vì vậy, biết tất cả điều này đây là một số mệnh đề để có được trở lại 60fps:

  1. Sử dụng độ phân giải giảm, ví dụ: 1280x720 thay vì 1920x1080, điều này sẽ làm giảm việc sử dụng băng thông & chế biến mảnh.Không lý tưởng tất nhiên, nhưng điều này có thể được sử dụng như một bài kiểm tra để xác nhận rằng bạn có vấn đề về dải hoặc đoạn (nếu bạn nhận được 60fps sau khi giảm độ phân giải, thì bạn có loại vấn đề này)
  2. Sử dụng bộ đệm sau 16 bit (R5G6B5) thay vì 32bits backbuffer (R8G8B8A8), điều này có thể làm giảm việc sử dụng băng thông, nhưng với một số tổn thất về chất lượng hình ảnh
  3. Giảm diện tích bề mặt được trộn: trong trường hợp của bạn, bạn nên tổ chức văn bản của mình theo "khối" nhiều nhất có thể nội dung giống như trong hình này từ IOS docs: enter image description here
  4. Tìm cách tắt Vsync trên thiết bị của bạn/sử dụng bộ đệm ba lần. Nếu bạn có quyền truy cập vào tài liệu Vivante GPU (tôi không), điều này có thể được mô tả bên trong.

Điểm 3 là điều tốt nhất để làm (đây là những gì được thực hiện trong hầu hết các trò chơi di động mà tôi đã làm), tuy nhiên điều này sẽ cần một số công việc phụ không đáng kể. Các điểm 1, 2 và 3 đơn giản hơn nhưng chỉ là "một nửa giải pháp".

+0

Cảm ơn bạn đây là câu trả lời rất chi tiết. Tôi đã có thể nhận được bản sao lưu fps của tôi đến 48 khung hình/giây bằng cách xóa nhiều cuộc gọi đáng tin cậy và có thể phát hiện đang xảy ra và không cần thiết. Các gpu dường như đồng bộ ở 30, 48 và 60fps. Một con đường mà tôi muốn thử khám phá là không có hỗ trợ KMS trên hạt nhân tôi hiện đang sử dụng và do đó không sao chép được thực hiện mà có thể tiết kiệm rất nhiều cuộc gọi memcpy. Nhưng công việc tốt đẹp, tiền thưởng được trao! – ReX357

+0

Cảm ơn bạn! Một lưu ý bổ sung: nếu bạn là GPU bị ràng buộc vì quad trong suốt toàn màn hình cho văn bản sau đó, tại một số điểm, bất kỳ tối ưu hóa bên CPU bạn thêm bạn sẽ nhận được không cải thiện fps hơn, và sau đó giải pháp duy nhất sẽ được tách quad lớn này trong quad phụ lắp các vùng văn bản hoặc giảm độ phân giải. Bạn có thể dễ dàng kiểm tra xem bạn có bị ràng buộc bởi GPU hay không bằng cách chuyển đổi quad của bạn thành opaque thay vì trong suốt hoặc bằng cách giảm độ phân giải, nếu bạn đạt được fps bằng cách thực hiện điều này thì GPU của bạn bị ràng buộc. –

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