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; }
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; }
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; }