博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NDK图形函数在某些机型下显示花屏的问题
阅读量:6823 次
发布时间:2019-06-26

本文共 2434 字,大约阅读时间需要 8 分钟。

NDK使用ANativeWindow渲染surface,

大致代码如下:

ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);if (nativeWindow == 0) {	LOGE("ANativeWindow_window_from_surface error;env[0x%x] surface[0x%x]", env, surface);	return NULL;}int err = ANativeWindow_setBuffersGeometry(nativeWindow, width, height, WINDOW_FORMAT_RGB_565);if ( err < 0 ) {	LOGE("ANativeWindow_setBuffersGeometry error");	return NULL;}LOGI("AnativeSurface_Draw param invalid. %d | %d | %d | %d | %d | %d", env, NativeSurface, ImgData, dataLen, width, height);if (env == NULL || NativeSurface == NULL || ImgData == NULL			|| dataLen == 0 || width == 0 || height == 0) {	LOGE("AnativeSurface_Draw param invalid. %d | %d | %d | %d | %d | %d", env, NativeSurface, ImgData, dataLen, width, height);	return ;}ANativeWindow_Buffer windowBuffer;int nlocked = ANativeWindow_lock((ANativeWindow*)NativeSurface, &windowBuffer, 0);if (nlocked < 0) {	LOGW("AnativeSurface lock error:%d", nlocked);	return;}if (windowBuffer.bits != NULL) {	memcpy(windowBuffer.bits, ImgData, dataLen);}ANativeWindow_unlockAndPost((ANativeWindow*)NativeSurface);ANativeWindow_release((ANativeWindow*)NativeSurface);
在测试的过程中,发现有些机型上出现花屏的现象,经内存拷贝测试,发现这些机型上,windowbuffer.bits的大小不等于 width * height * RGBSIZE,因此会导致数据错位而无法正常显示。

翻了下native_window.h(development/ndk/platforms/android-x/include/android目录下),对于windowBuffer的定义如下:

typedef struct ANativeWindow_Buffer {    // The number of pixels that are show horizontally.    int32_t width;    // The number of pixels that are shown vertically.    int32_t height;    // The number of *pixels* that a line in the buffer takes in    // memory.  This may be >= width.    int32_t stride;    // The format of the buffer.  One of WINDOW_FORMAT_*    int32_t format;    // The actual bits.    void* bits;        // Do not touch.    uint32_t reserved[6];} ANativeWindow_Buffer;
其中一个叫stride的项,表示在内存中每一行包含的像素数量,这个值可能会大于width。

再次测试,发现所有有问题的机型,果然stride大于width。因此在拷贝的时候需要注意内存对齐。。

最后解决方案如下:

if (windowBuffer.bits != NULL) {    	//memcpy(windowBuffer.bits, ImgData, dataLen);    	if (windowBuffer.width == windowBuffer.stride) {    		memcpy(windowBuffer.bits, ImgData, dataLen);    	} else {    		for (int ii=0; ii < windowBuffer.height; ii++) {    			char *srcPointer = ImgData + windowBuffer.width * ii * 2;    			char *dstPointer = ((char *)windowBuffer.bits) + windowBuffer.stride * ii * 2;    			memcpy(dstPointer, srcPointer, windowBuffer.width * 2);    		}    	}    }

转载地址:http://wslzl.baihongyu.com/

你可能感兴趣的文章
新学的的matplotlib库~~~~
查看>>
【树形dp】vijos P1180 选课
查看>>
实验三
查看>>
Codeforces Round #363 (Div. 2)
查看>>
HDU 6141 - I am your Father! | 2017 Multi-University Training Contest 8
查看>>
日期操作
查看>>
angularjs中ng-repeat-start与ng-repeat-end用法实例
查看>>
linux centos6.5 安装gcc-c++时出现 yum install gcc-c++ cannot find a valid baseurl for repo...
查看>>
Jsp动态生成表格
查看>>
MongoDB环境配置
查看>>
5_4 calvc
查看>>
Educational Codeforces Round 36 (Rated for Div. 2)
查看>>
深入理解javascript原型和闭包——从【自由变量】到【作用域链】
查看>>
Leetcode Sudoku Solver
查看>>
java多线程
查看>>
Navigator - BOM对象
查看>>
js中字符串的操作
查看>>
String类
查看>>
Hello Swift
查看>>
Codevs1029 遍历问题
查看>>