int init_framebuffer()
{
    struct fb_var_screeninfo vinfo;
    int fb = -1;

    struct fbinfo fbinfo;
    unsigned i, bytespp;
    //int w,h,f;
    //void const* base = 0;
    //size_t size = 0;

    int iversion = get_android_version();
    int busefb = 1;
    if( !g_forcefbmode && iversion >= 10 /* ICE_CREAM_SANDWICH */) {

		uint32_t w=0, h=0;
		PixelFormat fmt=0;
		int chk = 0;

        ScreenshotClient sc;
        //const String16 name("SurfaceFlinger");
        //sp<ISurfaceComposer> composer;
        //getService(name, &composer);
        //sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(0);
        //sp<IBinder> display(composer->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
        //sp<IBinder> display = composer->getBuiltInDisplay(id);
        //sc.update(display);
        sc.update();
        w = sc.getWidth();
        h = sc.getHeight();
        fmt = sc.getFormat();
        sc.release();

/*
		sp<IMemoryHeap> heap;

		sp<ISurfaceComposer> sf(ComposerService::getComposerService());

		sf->captureScreen(0, &heap, &w, &h, &fmt, 0, 0, 0,     0x7fffffff);
*/
        Log("fmt(%d), w(%d), h(%d)\n", fmt, w, h);
		if( set_fbinfo(fmt,w,h, &fbinfo) != 0 )
			busefb = 0;
    }

    if( busefb )
    { // not support screencap
            fb = open("/dev/graphics/fb0", O_RDONLY);
            if(fb < 0) {
                Err("Error:fb open error.\n");
                return 0;
            }

            if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) return 0;
            fcntl(fb, F_SETFD, FD_CLOEXEC);

            bytespp = vinfo.bits_per_pixel / 8;

            fbinfo.version = BEFORE_ICS;
            fbinfo.bpp = vinfo.bits_per_pixel;
            fbinfo.size = vinfo.xres * vinfo.yres * bytespp;
            fbinfo.width = vinfo.xres;
            fbinfo.height = vinfo.yres;
            fbinfo.red_offset = vinfo.red.offset;
            if( vinfo.red.msb_right !=0)
            {
            	Log("red MSB is on right\n");
            	fbinfo.red_offset = vinfo.bits_per_pixel - vinfo.red.offset - vinfo.red.length;
            }
            fbinfo.red_length = vinfo.red.length;
            fbinfo.red_mask = getMask(vinfo.red.length);

            fbinfo.green_offset = vinfo.green.offset;
            if( vinfo.green.msb_right != 0)
            {
            	Log("green MSB is on right\n");
            	fbinfo.green_offset = vinfo.bits_per_pixel - vinfo.green.offset - vinfo.green.length;
            }
            fbinfo.green_length = vinfo.green.length;
            fbinfo.green_mask = getMask(vinfo.green.length);

            fbinfo.blue_offset = vinfo.blue.offset;
            if( vinfo.blue.msb_right != 0)
            {
            	Log("blue MSB is on right\n");
            	fbinfo.blue_offset = vinfo.bits_per_pixel - vinfo.blue.offset - vinfo.blue.length;
            }
            fbinfo.blue_length = vinfo.blue.length;
            fbinfo.blue_mask = getMask(vinfo.blue.length);
            fbinfo.alpha_offset = vinfo.transp.offset;
            fbinfo.alpha_length = vinfo.transp.length;
            fbinfo.alpha_mask = getMask(vinfo.transp.length);

            close(fb);
    }

    fbinfo.orientation = 0; //get_dev_rotation();
    memcpy(&g_fbinfo, &fbinfo, sizeof(struct fbinfo));

    g_fbbuffer = (unsigned char*)malloc( fbinfo.width * fbinfo.height * 32/8);
    g_xsize = fbinfo.width * fbinfo.bpp / 8;
    g_x = (unsigned char*)malloc( fbinfo.width * 4);
    jpegBufSize = fbinfo.width * fbinfo.height * 32/8 * 2 / 3;
    fbc_output[0].jpegBuf = (char*)malloc( jpegBufSize );
#ifdef USE_XOR_MODE
    fbc_output[1].jpegBuf = (char*)malloc( jpegBufSize );
    memset(fbc_output[1].jpegBuf , 0, jpegBufSize);
#endif
    fbc_output_current = 0;

    int isBigEndian = is_big_endian();
    Log("xres=%d, yres=%d, bpp=%d red(off:%d,len:%d), green(%d,%d), blue(%d,%d)\n\
isBigEndian(%d), half(%d), forcefb(%d)\n",
      (int)fbinfo.width, (int)fbinfo.height,
      (int)fbinfo.bpp,
      (int) fbinfo.red_offset, (int)fbinfo.red_length,
      (int) fbinfo.green_offset, (int)fbinfo.green_length,
      (int) fbinfo.blue_offset, (int)fbinfo.blue_length,
      isBigEndian, g_halfmode, g_forcefbmode
      );
    if( fbinfo.version == ICS_SCREENCAP)
    	Log("Capturing Method : ICS_SCREENCAP\n");
    else
    	Log("Capturing Method : FB_ACCESS\n");

    int tresult = detect_touch_port(0);

    Log("Detect touch port : %d\n", tresult);

    return 1;
}
int read_rgb_framebuffer_screencap_to_jpeg(svcInfoPtr psvc)
{
#ifdef PERFORMANCE_REPORT
	struct timeval tS, tE;
	gettimeofday(&tS,NULL);
#endif
    void const* mapbase = 0;
    size_t size = 0;
    int nRtn;

    /*
    if (pscreenshot->update() == NO_ERROR) {
    	mapbase = pscreenshot->getPixels();
        //w = pscreenshot->getWidth();
        //h = pscreenshot->getHeight();
        //f = pscreenshot->getFormat();
        size = pscreenshot->getSize();
    }
    else {
    	Err("Error:ScreenshotClient init failed.\n");
    	return 0;
    }*/

    unsigned int sw, sh, xsize, gsize;
    sw = g_fbinfo.width;
    sh = g_fbinfo.height;
    xsize = g_xsize;
    gsize = g_fbinfo.size;
    if( g_halfmode) {
    	sw /= 2;
    	sh /= 2;
    	xsize /= 2;
    	gsize /= 4;
    }
        uint32_t w=0, h=0;
        PixelFormat fmt=0;

        //Log("w(%d) h(%d) sw(%d) sh(%d) xsize(%d) gsize(%d)\n", w, h, sw, sh, xsize, gsize);

        ScreenshotClient sc;
        sc.update(sw,sh);
        /*
        sp<IMemoryHeap> heap;
        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
        sf->captureScreen(0, &heap, &w, &h, &fmt, sw, sh, 0,     0x7fffffff);
        mapbase = heap->getBase();
        */

        mapbase = sc.getPixels();

        //Log("w(%d) h(%d) sw(%d) sh(%d) xsize(%d) gsize(%d)\n", w, h, sw, sh, xsize, gsize);
    if( mapbase != NULL) {
        unsigned char* base = (unsigned char*)((char const *)mapbase);
        unsigned char* p = g_fbbuffer;
        unsigned int i,j;

#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_capture += ELAPSED(tS, tE);
	tS = tE;
#endif
                init_jpeg(psvc->jpegquality);
#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_compress += ELAPSED(tS, tE);
	tS = tE;
#endif
                for(i=0; i< gsize; i += xsize) {
#ifdef USE_XOR_MODE
                	for(unsigned int t=0; t< xsize; t++)
                	{
                		*(g_x + t) = (*(fbc_output[1].jpegBuf + i + t) ^ *(base + t));
                	}
#else
				    memcpy(g_x, base, xsize);
#endif

#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_capture += ELAPSED(tS, tE);
	tS = tE;
#endif
              	  	nRtn = convert_to_rgb(g_x, xsize, p);
#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_colorspace += ELAPSED(tS, tE);
	tS = tE;
#endif
                    rowPointer[0] = p;
                    jpeg_write_scanlines(&cinfo, rowPointer, 1);
                    p += nRtn;
#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_compress += ELAPSED(tS, tE);
	tS = tE;
#endif
                    base += xsize;

                }

                if( gsize % xsize > 0 ) {
                	memcpy(g_x, base, gsize % xsize );

#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_capture += ELAPSED(tS, tE);
	tS = tE;
#endif
                    nRtn = convert_to_rgb(g_x, xsize, p);
#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_colorspace += ELAPSED(tS, tE);
	tS = tE;
#endif
					rowPointer[0] = p;
                    jpeg_write_scanlines(&cinfo, rowPointer, 1);
                    p += nRtn; 
#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_compress += ELAPSED(tS, tE);
	tS = tE;
#endif
                }
#ifdef USE_XOR_MODE
            	memcpy(fbc_output[1].jpegBuf , (unsigned char*)((char const *)mapbase), gsize);
#endif

                int nSize = exit_jpeg();

                // release sc
                sc.release();

                //Log("jpeg size:%d - ", nSize);
                if( nSize > 0 ) {
                	//FBCCMD res;

                	fbc_output[fbc_output_current].cmd = g_halfmode ? 'h' : 'u';
                	fbc_output[fbc_output_current].size = htonl(FBCCMD_HEADER + nSize);

                	LOCK(psvc->output_mutex);
                	int r1,r2;
                	r1 = WriteExact(psvc, (const char*)&fbc_output[fbc_output_current], FBCCMD_HEADER);
                	// actual data
                	//char * test = (char*)&fbc_output[fbc_output_current];
                	r2 = WriteExact(psvc, fbc_output[fbc_output_current].jpegBuf, nSize);
                	//Log("W1:%d W2:%d (%02x %02x %02x %02x %02x %02x %02x %02x\n", r1, r2,
                	//		test[0], test[1], test[2], test[3], test[4], test[5], test[6], test[7] );
                	UNLOCK(psvc->output_mutex);
                }

#ifdef PERFORMANCE_REPORT
	gettimeofday(&tE,NULL);

	psvc->frame_tx += ELAPSED(tS, tE);
	tS = tE;
#endif
                return nSize;

            }
            else {
                Err("map failed!!!\n");
            }
    return 0;
}
Example #3
0
int main(int argc, char** argv)
{
    const char* pname = argv[0];
    bool png = false;
    int c;
    while ((c = getopt(argc, argv, "ph")) != -1) {
        switch (c) {
            case 'p':
                png = true;
                break;
            case '?':
            case 'h':
                usage(pname);
                return 1;
        }
    }
    argc -= optind;
    argv += optind;

    int fd = -1;
    /*
    if (argc == 0) {
        fd = dup(STDOUT_FILENO);
    } else if (argc == 1) {
        const char* fn = argv[0];
        fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
        if (fd == -1) {
            fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
            return 1;
        }
        const int len = strlen(fn);
        if (len >= 4 && 0 == strcmp(fn+len-4, ".png")) {
            png = true;
        }
    }
    
    if (fd == -1) {
        usage(pname);
        return 1;
    }
    */

    void const* mapbase = MAP_FAILED;
    ssize_t mapsize = -1;

    void const* base = 0;
    uint32_t w, h, f;
    size_t size = 0;
    int i = 0;
    int ntest = 100;
    char fname[256];
    struct timeval tS, tE;
    double utime, mtime, seconds, useconds, average;



   gettimeofday(&tS, NULL);
    ScreenshotClient screenshot;
    for(i=0; i< ntest; i++) {

    sprintf(fname,"fb%02d.raw",i);
    fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0664);

    if (screenshot.update() == NO_ERROR) {
        base = screenshot.getPixels();
        w = screenshot.getWidth();
        h = screenshot.getHeight();
        f = screenshot.getFormat();
        size = screenshot.getSize();
    } else {
        printf("screenshot update failed - 2 \n");
        /*
        const char* fbpath = "/dev/graphics/fb0";
        int fb = open(fbpath, O_RDONLY);
        if (fb >= 0) {
            struct fb_var_screeninfo vinfo;
            if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) == 0) {
                uint32_t bytespp;
                if (vinfoToPixelFormat(vinfo, &bytespp, &f) == NO_ERROR) {
                    size_t offset = (vinfo.xoffset + vinfo.yoffset*vinfo.xres) * bytespp;
                    w = vinfo.xres;
                    h = vinfo.yres;
                    size = w*h*bytespp;
                    mapsize = offset + size;
                    mapbase = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, fb, 0);
                    if (mapbase != MAP_FAILED) {
                        base = (void const *)((char const *)mapbase + offset);
                    }
                }
            }
            close(fb);
        }
        */
    }

    if (base) {
        /*
        if (png) {
            SkBitmap b;
            b.setConfig(flinger2skia(f), w, h);
            b.setPixels((void*)base);
            SkDynamicMemoryWStream stream;
            SkImageEncoder::EncodeStream(&stream, b,
                    SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
            SkData* streamData = stream.copyToData();
            write(fd, streamData->data(), streamData->size());
            streamData->unref();
        } else 
        */
        {
            write(fd, &w, 4);
            write(fd, &h, 4);
            write(fd, &f, 4);
            write(fd, base, size);
        }
    }
    close(fd);
    if (mapbase != MAP_FAILED) {
        munmap((void *)mapbase, mapsize);
    }

    screenshot.release();
    printf("%d:%s\n", i+1, fname);
    gettimeofday(&tE, NULL);
    seconds = tE.tv_sec - tS.tv_sec;
    useconds= tE.tv_usec- tS.tv_usec;

    utime = seconds * 1000000 + useconds;
    printf("Elapsed:%.2f\n", utime/1000000 );
    usleep(1);
    }
    average = (double)ntest * 1000000 / utime ;
    printf("Elapsed:%.2f, Average:%.2f\n", utime/1000000, average);
    return 0;
}