[Nexus S Android Development] steven676:
That's an interesting observation, and I suspect you're right that it has something to do with the buffer. That said, I just can't find anything in the code or in the debugger that gives any clue as to what that might be -- perhaps it has to do with state that's internal to the PVR driver?

This is a bit of a disorganized infodump from my various bouts with gdb and webviewchromium, but here goes:

The EGL_NATIVE_BUFFER_ANDROID type to eglCreateImageKHR() is defined in the EGL_ANDROID_image_native_buffer extension (supported by our driver -- it's mandatory for Android EGL implementations). It tells us that the EGLClientBuffer (a typedef for (void *) ... god, I hate APIs that do this) passed in to the call must be a pointer to an ANativeWindowBuffer (system/core/include/system/window.h). That said, I've never seen webviewchromium pass anything other than a pointer to a GraphicBuffer (frameworks/native/include/ui/GraphicBuffer.h and frameworks/native/libs/ui/GraphicBuffer.cpp).

That GraphicBuffer is obtained via a call to CreateGpuMemoryBuffer() in an instance of ImageFactory (external/chromium_org/gpu/command_buffer/client/image_factory.h). But here's where things get strange: the only instance of ImageFactory that turns up in the entire Chromium codebase in searches via AndroidXref or Ohloh is GLInProcessContextImpl (external/chromium_org/gpu/command_buffer/client/gl_in_process_context.cc). That implementation delegates to an instance of GpuMemoryBufferFactory, which has only one implementation -- the Android WebView-specific GpuMemoryBufferFactoryImpl class (external/chromium_org/android_webview/browser/gpu_memory_buffer_factory_impl.{h,cpp}). That implementation obtains its GpuMemoryBuffer from the libwebviewchromium_plat_support library (frameworks/webview/chromium/plat_support/gpu_memory_buffer_impl.{h,cpp}), which gives it something which is basically a thin wrapper over libui's GraphicBuffer. In summary, by all appearances, this rendering path is specific to the Android WebView, which explains why Chrome for Android doesn't have this problem.

A quick examination of GpuMemoryBufferImpl in the plat_support library reveals the reason for the "mismatching lock usage flags" message on OMAP4: the buffer is always created with USAGE_HW_TEXTURE|USAGE_SW_READ_OFTEN|USAGE_SW_WRITE_OFTEN, but locked with one or both of USAGE_SW_READ_OFTEN or USAGE_SW_WRITE_OFTEN. (That message comes from the OMAP4-specific gralloc module, which explains why we don't see it on S5PC110.) But adjusting GpuMemoryBufferImpl so that the flags always match doesn't solve the problem. Other than that, I can't find anything remarkable in the way Chromium uses the GpuMemoryBuffer, though perhaps I haven't been looking hard enough in the right places -- maybe you (or someone else) will have more luck chasing this down.

We can't switch to the regular Chrome rendering path, because Chrome runs its GPU rendering in a separate process. I don't believe we can create new processes when initializing an Android WebView -- it's unsafe to fork() a multithreaded process unless the child process immediately exec()s another program, and the app using the WebView could have created any number of threads before initializing us. (That explains the separate "in-process" rendering pipeline for the Android WebView, where the GPU renderer runs in a thread of the main process.)

That said, we can try to avoid the use of EGLImages in the tile manager (external/chromium_org/cc/resources/tile_manager.cc). It appears that, when an ImageFactory instance isn't available, the tile manager will render into pixel buffers instead of EGLImages (external/chromium_org/cc/resources/{pixel_buffer,image}_raster_worker_pool.cc; the selection between the two is done when the tile manager initializes). Since ImageFactory appears to only be available through the Android WebView, I assume that Chrome uses the pixbuf renderer. (I haven't chased that down completely, so don't take that as gospel.)

It's possible to disable the use of EGLImages in the Android WebView with this brief patch (against external/chromium_org):

--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -56,8 +56,10 @@ bool AwMainDelegate::BasicStartupComplete(int* exit_code) {

CommandLine* cl = CommandLine::ForCurrentProcess();
cl->AppendSwitch(switches::kEnableBeginFrameScheduling);
+#if 0
if (!cl->HasSwitch("disable-map-image"))
cl->AppendSwitch(cc::switches::kUseMapImage);
+#endif

// WebView uses the Android system's scrollbars and overscroll glow.
cl->AppendSwitch(switches::kHideScrollbars);

That eliminates the black tiles, but the rendering still doesn't work correctly -- you now sometimes get tiles that are blank except for the background color of the webpage in question (no text or images). I guess no one's tested the pixbuf renderer in the WebView-specific in-process rendering path in a while? That said, it may be worth pursuing this further -- it seems likely that this is a bug in the Android WebView or Chromium, which we can (in principle) find and fix. By contrast, the EGLImage problem seems likely to be a GPU driver bug, which we're struggling to characterize in the first place, and which we can probably at best try to work around by avoiding the broken functionality.

Must ... sleep ... now ...... zzzzzzzzzzzzzzzz.