Home | History | Annotate | Download | only in test
      1 /*
      2 // Copyright(c)2014 IntelCorporation
      3 //
      4 // LicensedundertheApacheLicense,Version2.0(the"License");
      5 // youmaynotusethisfileexceptincompliancewiththeLicense.
      6 // YoumayobtainacopyoftheLicenseat
      7 //
      8 // http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software
     11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS,
     12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
     13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand
     14 // limitationsundertheLicense.
     15 */
     16 #include <gtest/gtest.h>
     17 
     18 #include <binder/IMemory.h>
     19 
     20 #include <gui/ISurfaceComposer.h>
     21 #include <gui/Surface.h>
     22 #include <gui/SurfaceComposerClient.h>
     23 #include <private/gui/ComposerService.h>
     24 
     25 #include <utils/String8.h>
     26 
     27 using namespace android;
     28 const char * filename = "/data/my_640x480.nv12";
     29 #define PIXEL_FORMAT_NV12 0x7FA00E00
     30 
     31 // Fill a YV12 buffer with a multi-colored checkerboard pattern
     32 void fillYUVBuffer(uint8_t* buf, int w, int h, int stride) {
     33 	const int blockWidth = w > 16 ? w / 16 : 1;
     34 	const int blockHeight = h > 16 ? h / 16 : 1;
     35 	const int yuvTexOffsetY = 0;
     36 	int yuvTexStrideY = stride;
     37 	int yuvTexOffsetV = yuvTexStrideY * h;
     38 	int yuvTexStrideV = (yuvTexStrideY / 2 + 0xf) & ~0xf;
     39 	int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h / 2;
     40 	int yuvTexStrideU = yuvTexStrideV;
     41 	for (int x = 0; x < w; x++) {
     42 		for (int y = 0; y < h; y++) {
     43 			int parityX = (x / blockWidth) & 1;
     44 			int parityY = (y / blockHeight) & 1;
     45 			unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
     46 			buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
     47 			if (x < w / 2 && y < h / 2) {
     48 				buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
     49 				if (x * 2 < w / 2 && y * 2 < h / 2) {
     50 					buf[yuvTexOffsetV + (y * 2 * yuvTexStrideV) + x * 2 + 0] =
     51 							buf[yuvTexOffsetV + (y * 2 * yuvTexStrideV) + x * 2
     52 									+ 1] =
     53 									buf[yuvTexOffsetV
     54 											+ ((y * 2 + 1) * yuvTexStrideV)
     55 											+ x * 2 + 0] = buf[yuvTexOffsetV
     56 											+ ((y * 2 + 1) * yuvTexStrideV)
     57 											+ x * 2 + 1] = intensity;
     58 				}
     59 			}
     60 		}
     61 	}
     62 }
     63 
     64 void loadYUVBufferFromFile(uint8_t* buf, int w, int h, int stride) {
     65 	FILE *fp = fopen(filename, "r");
     66 	int line = 0;
     67 	int offset = 0;
     68 	int buffer_height = h * 1.5;
     69 
     70 	if (!fp) {
     71 		printf("%s: failed to open %s\n", __func__, filename);
     72 		return;
     73 	}
     74 
     75 	printf("buf=%p, w=%d,h=%d,stride=%d\n", buf, w, h, stride);
     76 
     77 	for (line = 0; line < buffer_height; line++) {
     78 		printf("reading line %d...\n", line);
     79 		offset = line * stride;
     80 		fread(buf + offset, w, 1, fp);
     81 	}
     82 
     83 	fclose(fp);
     84 }
     85 
     86 int main(int argc, char **argv) {
     87 	sp < SurfaceControl > sc;
     88 	sp < Surface > s;
     89 	sp < ANativeWindow > anw;
     90 	ANativeWindowBuffer *anb;
     91 	uint8_t* img = NULL;
     92 	sp < SurfaceComposerClient > composerClient = new SurfaceComposerClient;
     93 	if (composerClient->initCheck() != NO_ERROR)
     94 		return 0;
     95 
     96 	sc = composerClient->createSurface(String8("FG Test Surface"), 640, 480,
     97 			PIXEL_FORMAT_RGBA_8888, 0);
     98 	if (sc == NULL)
     99 		return 0;;
    100 	if (!sc->isValid())
    101 		return 0;
    102 
    103 	s = sc->getSurface();
    104 	anw = s.get();
    105 	if (native_window_set_buffers_geometry(anw.get(), 640, 480,
    106 			PIXEL_FORMAT_NV12) != NO_ERROR)
    107 		return 0;
    108 	if (native_window_set_usage(anw.get(),
    109 			GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)
    110 			!= NO_ERROR)
    111 		return 0;
    112 
    113 	/*
    114 	 * load buffer
    115 	 */
    116 	if (native_window_dequeue_buffer_and_wait(anw.get(), &anb))
    117 		return 0;
    118 	if (anb == NULL)
    119 		return 0;
    120 	sp <GraphicBuffer> buf(GraphicBuffer::from(anb));
    121 	//if (anw->lockBuffer(anw.get(), buf->getNativeBuffer()) != NO_ERROR)
    122 	//	return 0;
    123 	buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**) (&img));
    124 	if (!img) {
    125 		printf("failed to lock buffer\n");
    126 		exit(-1);
    127 	}
    128 
    129 	loadYUVBufferFromFile(img, 640, 480, buf->getStride());
    130 	buf->unlock();
    131 	printf("querying buffer...\n");
    132 	if (anw->queueBuffer(anw.get(), buf->getNativeBuffer(), -1) != NO_ERROR)
    133 		return 0;
    134 
    135 	// loop it to continuously display??
    136 	while (1) {
    137 		SurfaceComposerClient::openGlobalTransaction();
    138 		if (sc->setLayer(INT_MAX - 1) != NO_ERROR)
    139 			return 0;
    140 		if (sc->show() != NO_ERROR)
    141 			return 0;
    142 
    143 		SurfaceComposerClient::closeGlobalTransaction();
    144 	}
    145 	return 0;
    146 }
    147 
    148