int initFB(void) {
	L("--Initializing framebuffer access method--\n");
	
	fbmmap = MAP_FAILED;
	
	if ((fbfd = open(framebuffer_device, O_RDWR)) == -1) {
		L("Cannot open fb device %s\n", framebuffer_device);
		return -1;
	}
	
	update_fb_info();
	
	if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscrinfo) != 0) {
		L("ioctl error\n");
		return -1;
	}
	
	L("line_length=%d xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n",
		(int)fscrinfo.line_length,(int)scrinfo.xres, (int)scrinfo.yres,
		(int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual,
		(int)scrinfo.xoffset, (int)scrinfo.yoffset,
		(int)scrinfo.bits_per_pixel);
	
	size_t size = scrinfo.yres_virtual;
	
	size_t fbSize = roundUpToPageSize(fscrinfo.line_length * size);
	
	fbmmap = mmap(NULL, fbSize , PROT_READ|PROT_WRITE ,  MAP_SHARED , fbfd, 0);
	
	if (fbmmap == MAP_FAILED) {
		L("mmap failed\n");
		return -1;
	}
	
	// always scale down by 2
	screenformat.width = scrinfo.xres / 2;
	screenformat.height = scrinfo.yres / 2;
	
	// constants for RGB565
	screenformat.bitsPerPixel = 16;
	screenformat.size = screenformat.width * screenformat.height * screenformat.bitsPerPixel / CHAR_BIT;
	screenformat.redShift = 11;
	screenformat.redMax = 5;
	screenformat.greenShift = 5;
	screenformat.greenMax = 6;
	screenformat.blueShift = 0;
	screenformat.blueMax = 5;
	
	return 1;
}
OMX_ERRORTYPE IpulibRender::FBInit()
{
	int  retval = 0;
#ifdef ANDROID_BUILD
	OMX_STRING device_name = (OMX_STRING)"/dev/graphics/fb1";
#else
	OMX_STRING device_name = (OMX_STRING)"/dev/fb1";
#endif
	struct fb_var_screeninfo screen_info;
	struct fb_fix_screeninfo fscreeninfo;

	GetFBResolution(0, &nFBWidth, &nFBHeight);

	mFb = open(device_name, O_RDWR | O_NONBLOCK, 0);
	if(mFb < 0)
	{
		LOG_ERROR("Open device: %d failed.\n", device_name);
		return OMX_ErrorHardware;
	}

	retval = ioctl(mFb, FBIOGET_VSCREENINFO, &screen_info);
	if (retval < 0)
	{
		close(mFb);
		return OMX_ErrorHardware;
	}

	screen_info.xoffset = 0;
	screen_info.yoffset = 0;
	screen_info.bits_per_pixel = 16;
	screen_info.nonstd = V4L2_PIX_FMT_UYVY;
	screen_info.activate = FB_ACTIVATE_NOW;
	screen_info.xres = nFBWidth;
	screen_info.yres = nFBHeight;
	screen_info.yres_virtual = screen_info.yres * MAX_FB_BUFFERS;
	screen_info.xres_virtual = screen_info.xres;
	retval = ioctl(mFb, FBIOPUT_VSCREENINFO, &screen_info);
	if (retval < 0)
	{
		close(mFb);
		return OMX_ErrorHardware;
	}

	retval = ioctl(mFb, FBIOGET_FSCREENINFO, &fscreeninfo);
	if (retval < 0)
	{
		close(mFb);
		return OMX_ErrorHardware;
	}

	pFbPAddrBase = (OMX_PTR)fscreeninfo.smem_start;
	nFbSize = roundUpToPageSize(fscreeninfo.line_length * screen_info.yres_virtual);
	pFbVAddrBase = (unsigned short *)mmap(0, nFbSize, PROT_READ | PROT_WRITE, MAP_SHARED, mFb, 0);
	if ((int)pFbVAddrBase <= 0)
	{
		LOG_ERROR("Failed to map framebuffer2.\n");
		munmap(pFbVAddrBase, nFbSize);
		close(mFb);
		return OMX_ErrorHardware;
	}

	OMX_S32 i=0;
	OMX_S16 *pBuffer = (OMX_S16*)pFbVAddrBase;
	for(i=0; i<nFbSize/2; i++, pBuffer++)
		*pBuffer = 0x80;

	retval = ioctl(mFb, FBIOBLANK, FB_BLANK_UNBLANK);
	if (retval < 0)
	{
		munmap(pFbVAddrBase, nFbSize);
		close(mFb);
		return OMX_ErrorHardware;
	}

	OMX_S32 nBufferSize = nFbSize / MAX_FB_BUFFERS;
	for(i=0; i<MAX_FB_BUFFERS; i++)
		pFbPAddr[i] = (OMX_U8 *)pFbPAddrBase + i * nBufferSize;
	nNextFb = 0;

	return OMX_ErrorNone;
}
Esempio n. 3
0
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle)
{
    int err = 0;
    int flags = 0;

    int fd = -1;
    void* base = 0; // XXX JMG: This should change to just get an address from
                    // the PmemAllocator rather than getting the base & offset separately
    int offset = 0;
    int lockState = 0;

    size = roundUpToPageSize(size);

    if (usage & GRALLOC_USAGE_HW_TEXTURE) {
        // enable pmem in that case, so our software GL can fallback to
        // the copybit module.
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_HW_2D) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
        flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);

    if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
        (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {

        PmemAllocator* pma = 0;

        if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) {
          if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
              LOGE("attempting to allocate a gralloc buffer with both the "
                   "USES_PMEM and USES_PMEM_ADSP flags.  Unsetting the "
                   "USES_PMEM_ADSP flag.");
              flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
          }
          pma = &pmemAllocator;
        } else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0
          pma = &pmemAdspAllocator;
        }

        // PMEM buffers are always mmapped
        lockState |= private_handle_t::LOCK_STATE_MAPPED;

        // Allocate the buffer from pmem
        err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd);
        if (err < 0) {
            if (((usage & GRALLOC_USAGE_HW_MASK) == 0) &&
                ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) == 0)) {
                // the caller didn't request PMEM, so we can try something else
                flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
                err = 0;
                goto try_ashmem;
            } else {
                LOGE("couldn't open pmem (%s)", strerror(errno));
            }
        }
    } else {
try_ashmem:
        fd = deps.ashmem_create_region("gralloc-buffer", size);
        if (fd < 0) {
            LOGE("couldn't create ashmem (%s)", strerror(errno));
            err = -errno;
        }
    }

    if (err == 0) {
        private_handle_t* hnd = new private_handle_t(fd, size, flags);
        hnd->offset = offset;
        hnd->base = int(base)+offset;
        hnd->lockState = lockState;
        *pHandle = hnd;
    }

    LOGE_IF(err, "gralloc failed err=%s", strerror(-err));

    return err;
}
static int get_framebuffer(GGLSurface *fb)
{
    int fd;
    void *bits;

    fd = open("/dev/graphics/fb0", O_RDWR);
    if (fd < 0) {
        perror("cannot open fb0");
        return -1;
    }

    if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
        perror("failed to get fb0 info");
        close(fd);
        return -1;
    }
#if 0
    fprintf(stderr, "\tGetting VSCREENINFO\n");
    fprintf(stderr, "\t\txres=%u, yres=%u\n", vi.xres, vi.yres);
    fprintf(stderr, "\t\txres_virtual=%u, yres_virtual=%u\n", vi.xres_virtual, vi.yres_virtual);
    fprintf(stderr, "\t\txoffset=%u, yoffset=%u\n", vi.xoffset, vi.yoffset);
    fprintf(stderr, "\t\tbits_per_pixel=%u, grayscale=%u\n", vi.bits_per_pixel, vi.grayscale);
    fprintf(stderr, "\t\tred:\n\t\t\toffset=%u, length=%u, msb_right=%u\n", vi.red.offset, vi.red.length, vi.red.msb_right);
    fprintf(stderr, "\t\tgreen:\n\t\t\toffset=%u, length=%u, msb_right=%u\n", vi.green.offset, vi.green.length, vi.green.msb_right);
    fprintf(stderr, "\t\tblue:\n\t\t\toffset=%u, length=%u, msb_right=%u\n", vi.blue.offset, vi.blue.length, vi.blue.msb_right);
    fprintf(stderr, "\t\ttransp:\n\t\t\toffset=%u, length=%u, msb_right=%u\n", vi.transp.offset, vi.transp.length, vi.transp.msb_right);
    fprintf(stderr, "\t\tnonstd=%u, activate=%u\n", vi.nonstd, vi.activate);
    fprintf(stderr, "\t\theight=%u, width=%u\n", vi.height, vi.width);
    fprintf(stderr, "\t\taccel_flags=%u, pixclock=%u\n", vi.accel_flags, vi.pixclock);
    fprintf(stderr, "\t\tleft_margin=%u, right_margin=%u\n", vi.left_margin, vi.right_margin);
    fprintf(stderr, "\t\tupper_margin=%u, lower_margin=%u\n", vi.upper_margin, vi.lower_margin);
    fprintf(stderr, "\t\thsync_len=%u, vsync_len=%u\n", vi.hsync_len, vi.vsync_len);
    fprintf(stderr, "\t\tsync=%u, vmode=%u\n", vi.sync, vi.vmode);
    fprintf(stderr, "\t\trotate=%u, reserved={%u,%u,%u,%u,%u}\n", vi.rotate, vi.reserved[0], vi.reserved[1], vi.reserved[2], vi.reserved[3], vi.reserved[4]);
#endif

    switch (vi.bits_per_pixel) {
    case 16:
        PIXEL_SIZE = 2;
        PIXEL_FORMAT = GGL_PIXEL_FORMAT_RGB_565;
        break;
    case 24:
        PIXEL_SIZE = 3;
        PIXEL_FORMAT = GGL_PIXEL_FORMAT_RGB_888;
        break;
    case 32:
        PIXEL_SIZE = 4;
        if(vi.red.offset == 8)
            PIXEL_FORMAT = GGL_PIXEL_FORMAT_BGRA_8888;
        else if(vi.transp.length == 0)
            PIXEL_FORMAT = GGL_PIXEL_FORMAT_RGBX_8888;
        else
            PIXEL_FORMAT = GGL_PIXEL_FORMAT_RGBA_8888;
        break;
    default:
        perror("Unknown Pixel Format\n");
        close(fd);
        return -1;
    }

    if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
        perror("failed to get fb0 info");
        close(fd);
        return -1;
    }

    //printf("fi.smem_len=%d, vi.yres=%d, fi.line_length=%d\n",fi.smem_len,vi.yres,fi.line_length);

    bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);//auto roundUpToPageSize
    if (bits == MAP_FAILED) {
        perror("failed to mmap framebuffer");
        close(fd);
        return -1;
    }

    fb->version = sizeof(*fb);
    fb->width = vi.xres;
    fb->height = vi.yres;
    fb->stride = fi.line_length/PIXEL_SIZE;
    fb->data = bits;
    fb->format = PIXEL_FORMAT;
    memset(fb->data, 0,roundUpToPageSize(vi.yres * fi.line_length));

    fb++;

    /* check if we can use double buffering */
    if (roundUpToPageSize(vi.yres * fi.line_length) * 2 > roundUpToPageSize(fi.smem_len))
        return fd;

    double_buffering = 1;

    fb->version = sizeof(*fb);
    fb->width = vi.xres;
    fb->height = vi.yres;
    fb->stride = fi.line_length/PIXEL_SIZE;
    fb->data = (void*) (((unsigned) bits) + roundUpToPageSize(vi.yres * fi.line_length));
    fb->format = PIXEL_FORMAT;
    memset(fb->data, 0, roundUpToPageSize(vi.yres * fi.line_length));

    return fd;
}
Esempio n. 5
0
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle,
                                        int bufferType, int format, int width, int height)
{
    int err = 0;
    int flags = 0;

    int fd = -1;
    void* base = 0; // XXX JMG: This should change to just get an address from
                    // the PmemAllocator rather than getting the base & offset separately
    int offset = 0;
    int lockState = 0;

    size = roundUpToPageSize(size);
#ifndef USE_ASHMEM
    if (usage & GRALLOC_USAGE_HW_TEXTURE) {
        // enable pmem in that case, so our software GL can fallback to
        // the copybit module.
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_HW_2D) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }
#else
    // Enable use of PMEM only when MDP composition is used (and other conditions apply).
    // Else fall back on using ASHMEM
    if ((get_composition_type() == MDP_COMPOSITION) &&
        ((usage & GRALLOC_USAGE_HW_TEXTURE) || (usage & GRALLOC_USAGE_HW_2D)) ) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_PRIVATE_PMEM) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }
#endif
    if ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) || (usage & GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL)
        || (usage & GRALLOC_USAGE_EXTERNAL_DISP) || (usage & GRALLOC_USAGE_PROTECTED)) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
        flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
    if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 &&
       (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) {
       flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
       err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
       if(err >= 0)
            lockState |= private_handle_t::LOCK_STATE_MAPPED; 
    }
    else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
        (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {

        PmemAllocator* pma = 0;

        if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) {
          if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
              LOGE("attempting to allocate a gralloc buffer with both the "
                   "USES_PMEM and USES_PMEM_ADSP flags.  Unsetting the "
                   "USES_PMEM_ADSP flag.");
              flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
          }
          pma = &pmemAllocator;
        } else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0
          pma = &pmemAdspAllocator;
        }

        // PMEM buffers are always mmapped
        lockState |= private_handle_t::LOCK_STATE_MAPPED;

        err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd, format);
        if (err < 0) {
            // Pmem allocation failed. Try falling back to ashmem iff we are:
            // a. not using MDP composition
            // b. not allocating memory for a buffer to be used by overlays
            // c. The client has not explicitly requested a PMEM buffer
            if ((get_composition_type() != MDP_COMPOSITION) &&
                (bufferType != BUFFER_TYPE_VIDEO) &&
                ((usage & GRALLOC_USAGE_PRIVATE_PMEM) == 0) &&
                ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) == 0)) {
                // the caller didn't request PMEM, so we can try something else
                flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
                err = 0;
                LOGE("Pmem allocation failed. Trying ashmem");
                goto try_ashmem;
            } else {
                LOGE("couldn't open pmem (%s)", strerror(errno));
            }
        }
    } else {
try_ashmem:
        err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
        if (err >= 0) {
            lockState |= private_handle_t::LOCK_STATE_MAPPED;
            flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
        } else {
            LOGE("Ashmem fallback failed");
        }
    }

    if (err == 0) {
        private_handle_t* hnd = new private_handle_t(fd, size, flags, bufferType, format, width, height);
        hnd->offset = offset;
        hnd->base = int(base)+offset;
        hnd->lockState = lockState;
        *pHandle = hnd;
    }

    LOGE_IF(err, "gralloc failed err=%s", strerror(-err));

    return err;
}