2015-05-19 28 views
0

我在使用Android NDK的OpenGL應用程序中混合了一個圖形故障。adb screencap輸出與設備上的不同

奇怪的是,當我通過adb screencap命令截圖時,問題完全消失,結果看起來沒問題。

我的問題是: 有沒有辦法知道背後的幕後製作截圖?例如,是否有eglChooseConfig用整個框架的某些特定值調用?或者也許有一些特定的初始GL狀態被迫?

一些背景:當我打電話glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)一些幾何

我的設備所採用了高通的Adreno 320

發生的glich。

我也發現設置glColorMask(1, 1, 1, 0)會導致我的設備(僅在此設備上)出現黑屏,而截取屏幕會產生完整的正確遊戲幀。

該應用程序不會在其他幾個Android設備上輸出故障,其他應用程序也可以正常工作,即使那些使用大量混合的應用程序也能正常工作。

回答

1

的問題消失,一旦我註釋掉EGL_ALPHA_SIZE設置:

const EGLint attribs[] = { 
    EGL_BLUE_SIZE, 8, 
    EGL_GREEN_SIZE, 8, 
    EGL_RED_SIZE, 8, 
    //EGL_ALPHA_SIZE, 8, 
    EGL_NONE 
}; 

它看起來像具有α設置爲8位,eglChooseConfig返回有問題的配置對象。

有趣的是,「正確的」EGLConfig指定0位爲EGL_ALPHA_SIZE,所以起初我希望它根本不工作。其他設備並不真正關心這個價值,他們做得很好,只提供了RGB通道的深度。

我已經吸取了教訓:如果設備上有圖形故障,請檢查所有可能的EGL配置!

所以我的結論是:是的,可能是在adb screencap裏面有一個自定義的EGLConfig集合。

+1

FWIW,Grafika選擇alpha大小爲8(https://github.com/google/grafika/blob/master/src/com/android/grafika/gles/EglCore.java#L144),我從未見過任何奇怪的東西。我猜想大多數GLES應用程序都使用這種配置(32位RGBA)。屏幕截圖代碼組合了呈現的輸出,我不希望用於blitting的EGL配置具有「修復」渲染的效果。所以這是一個非常有趣的數據點,但我懷疑還有更多。這可能是值得恢復的alpha大小,並添加'EGL_RENDERABLE_TYPE'看看這是否也改變了事情。 – fadden

+0

對 - 我沒有想到這些其他配置變量。雖然,我已經嘗試了所有9個配置,但未註釋EGL_ALPHA_SIZE,它們都產生了不正確的結果。 我不認爲解決這個謎題值得付出努力,它很可能是這些模型已知的驅動程序錯誤之一,並且這個模型甚至不支持glBlendFuncSeparate(!) –

2

一般來說,設備沒有一個幀緩衝器可以在捕捉屏幕時複製出來。 「屏幕截圖」功能實際上是「將屏幕重新繪製成緩衝區」功能。如果屏幕上顯示「安全」圖層或DRM內容,屏幕截圖可能會略有不同,故意這樣做。

這是一個單一的,完全不透明的表面?或者它與上面或下面的其他圖層混合在一起?

差異的最常見原因是硬件編寫器中的錯誤,但聽起來好像你看到的問題在單一表面上渲染,所以這是不太可能的。如果您擁有根設備,則可以使用顯示的命令打開和關閉HWC組合:hereadb shell service call SurfaceFlinger 1008 i32 1將禁用疊加並強制GLES組合。 (如果沒有任何意義,請通讀graphics architecture文檔。)

您是否能夠發佈正確和故障圖像的圖像? (一個通過屏幕截圖,一個通過使用第二個設備拍攝該設備的圖片。)

如果使用adb shell screenrecord錄製屏幕,您是否會看到類似的問題?

+0

非常感謝您的寶貴意見。在解決這個問題之前,先了解一下你提供的提示。我會接受我自己的答案,以便每個人都能看到問題的真正原因,但是你有我的讚賞。 –