4 ms·
Cargo cult is the result of a trap that our own brain seem to be wired to fall in. Yeah, tell me about it. I fell into the trap a couple of months ago. I was
by antimagic 13y ago
Cargo cult is the result of a trap that our own brain seem to be wired to fall in.
Yeah, tell me about it. I fell into the trap a couple of months ago. I was tasked with porting my company's browser's 2D graphics backend onto Android OpenGL. My first attempt allowed the browser to draw into graphics buffers that I would load into a texture using glTexImage2D.
A few co-workers felt that this was less efficient than the old 2D APIs, where we would draw into a buffer that would be directly read by the blitter hardware, without having to do a load step. I agreed - on the face of it, if we could arrange things to draw into the texture buffer directly we could save memory and processor cycles, so I started hunting on the Internet to see if anyone else had come to the same conclusion.
It turns out that the guys that were developing Firefox for Android had had exactly the same problem, and they hacked together a solution where they used some internal Android APIs for graphic buffers, that they accessed through dlopen/dlsym. They then linked the buffer to an eglImage, and created a texture from the eglImage. I figured that hey, if the Firefox guys are doing it, then it's probably not to bad an idea.
Unfortunately I should have taken the next step in my investigations, and ask myself exactly what that code that created an eglImage and linked it to a texture was actually doing. If I had investigated that more closely, I would have realised that behind the scenes there's an implicit equivalent of glTexImage2D being done - the problem being that the internal format of a texture is not a simple bitmap. The image is tiled so that OpenGL can draw a texture to the screen with any rotation and have roughly the same performance - if you use a standard bitmap layout, memory paging makes drawing tall thin rectangles much slower than drawing wide short rectangles. So, for OpenGL (or at least OpenGL ES) to be able to draw the texture to the screen, it first reads the data in from the eglImage, tiling it as it goes. This is exactly the same workload that you have in glTexImage2D, and it requires you to keep two copies of the buffer - the one you draw into, and the one that has been tiled for OpenGL.
Anyway, it took me about a month to get the eglImage solution to work (apart from everything else, you are exposed to odd behaviour by the graphics libraries of each Android tablet that your code runs on, that you have to write special code to handle, ie it's not very portable as a solution). Once I realised that I wasn't actually gaining anything from the exercise, I had to go and rip out all of that native graphic buffer code, and put back in the original standard texture code. I probably wasted 6 weeks stuffing around with all of this.
Lesson learned - if you are worrying about optimising code, you need to understand what is being done by the compiler / hardware, and it is pointless changing code until you have that understanding. Don't just accept stuff that you read on the Internet, where possible you need to go and look at source code, or official documentation. Anything else is running the risk of cargo-culting.