Esempio n. 1
0
int ompi_free_list_init_ex(
    ompi_free_list_t *flist,
    size_t elem_size,
    size_t header_space,
    size_t alignment,
    opal_class_t* elem_class,
    int num_elements_to_alloc,
    int max_elements_to_alloc,
    int num_elements_per_alloc,
    mca_mpool_base_module_t* mpool)
{
    if(elem_size > flist->fl_elem_size)
        flist->fl_elem_size = elem_size;
    if(elem_class)
        flist->fl_elem_class = elem_class;
    flist->fl_max_to_alloc = max_elements_to_alloc;
    flist->fl_num_allocated = 0;
    flist->fl_num_per_alloc = num_elements_per_alloc;
    flist->fl_mpool = mpool;
    flist->fl_header_space = header_space;
    flist->fl_alignment = alignment;
    flist->fl_elem_size = align_to(flist->fl_elem_size, flist->fl_alignment);
    if(num_elements_to_alloc)
        return ompi_free_list_grow(flist, num_elements_to_alloc);
    return OMPI_SUCCESS;
}
Esempio n. 2
0
    static uint32_t getMipLevelPackedDataSize(const Texture* pTexture, uint32_t mipLevel)
    {
        assert(mipLevel < pTexture->getMipCount());
        ResourceFormat format = pTexture->getFormat();

        uint32_t w = pTexture->getWidth(mipLevel);
        uint32_t perW = getFormatWidthCompressionRatio(format);
        uint32_t bw = align_to(perW, w) / perW;

        uint32_t h = pTexture->getHeight(mipLevel);
        uint32_t perH = getFormatHeightCompressionRatio(format);
        uint32_t bh = align_to(perH, h) / perH;

        uint32_t d = pTexture->getDepth(mipLevel);

        uint32_t size = bh * bw * d * getFormatBytesPerBlock(format);
        return size;
    }
bool IntelSpritePlane::setDataBuffer(IntelDisplayBuffer& buffer)
{
    if (initCheck()) {
        IntelDisplayBuffer *bufferPtr = &buffer;
        IntelDisplayDataBuffer *spriteDataBuffer =
	            reinterpret_cast<IntelDisplayDataBuffer*>(bufferPtr);
        IntelSpriteContext *spriteContext =
            reinterpret_cast<IntelSpriteContext*>(mContext);
        intel_sprite_context_t *context = spriteContext->getContext();

        uint32_t format = spriteDataBuffer->getFormat();
        uint32_t spriteFormat;
        int bpp;

        switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
            spriteFormat = INTEL_SPRITE_PIXEL_FORMAT_RGBA8888;
            bpp = 4;
            break;
        case HAL_PIXEL_FORMAT_RGBX_8888:
            spriteFormat = INTEL_SPRITE_PIXEL_FORMAT_RGBX8888;
            bpp = 4;
            break;
        case HAL_PIXEL_FORMAT_BGRA_8888:
            spriteFormat = INTEL_SPRITE_PIXEL_FORMAT_BGRA8888;
            bpp = 4;
            break;
        default:
            ALOGE("%s: unsupported format 0x%x\n", __func__, format);
            return false;
        }

        // set offset;
        int srcX = spriteDataBuffer->getSrcX();
        int srcY = spriteDataBuffer->getSrcY();
        int srcWidth = spriteDataBuffer->getSrcWidth();
        int srcHeight = spriteDataBuffer->getSrcHeight();
        uint32_t stride = align_to(bpp * srcWidth, 64);
        uint32_t linoff = srcY * stride + srcX * bpp;

        // gtt
        uint32_t gttOffsetInPage = spriteDataBuffer->getGttOffsetInPage();

        // update context
        context->cntr = spriteFormat | 0x80000000;
        context->linoff = linoff;
        context->stride = stride;
        context->surf = gttOffsetInPage << 12;
        context->update_mask = SPRITE_UPDATE_ALL;

        return true;
    }
    ALOGE("%s: sprite plane was not initialized\n", __func__);
    return false;
}
Esempio n. 4
0
/// @summary Allocates memory using malloc with alignment.
/// @param size_in_bytes The amount of memory being requested.
/// @param alignment The desired power-of-two alignment of the returned address.
/// @param actual On return, stores the number of bytes actually allocated.
/// @return A pointer to a memory block whose address is an even integer multiple
/// of alignment, and whose size is at least size_in_bytes, or NULL.
static void* allocate_aligned(size_t size_in_bytes, size_t alignment, size_t &actual)
{
    size_t   total_size = size_in_bytes + sizeof(uintptr_t); // allocate enough extra to store the base address
    size_t   alloc_size = align_up(total_size, alignment);   // allocate enough extra to properly align
    uint8_t *mem_ptr    = (uint8_t*) malloc(alloc_size);     // allocate the raw memory block
    uint8_t *aln_ptr    = align_to(mem_ptr, alignment);      // calculate the aligned address
    uint8_t *base       = aln_ptr - sizeof(uintptr_t);       // where to store the address returned by malloc
    *(uintptr_t*)base   = (uintptr_t) mem_ptr;               // store the address returned by malloc
    actual = alloc_size;
    return aln_ptr;
}
Esempio n. 5
0
int ompi_free_list_grow(ompi_free_list_t* flist, size_t num_elements)
{
    unsigned char* ptr;
    ompi_free_list_memory_t *alloc_ptr;
    size_t i, alloc_size;
    mca_mpool_base_registration_t* user_out = NULL; 

    if (flist->fl_max_to_alloc > 0)
        if (flist->fl_num_allocated + num_elements > flist->fl_max_to_alloc)
            num_elements = flist->fl_max_to_alloc - flist->fl_num_allocated;

    if (num_elements == 0)
        return OMPI_ERR_TEMP_OUT_OF_RESOURCE;

    alloc_size = num_elements * flist->fl_elem_size +
        sizeof(ompi_free_list_memory_t) + flist->fl_header_space +
        flist->fl_alignment;

    if (NULL != flist->fl_mpool)
        alloc_ptr = (ompi_free_list_memory_t*)flist->fl_mpool->mpool_alloc(flist->fl_mpool, 
                                                                           alloc_size, 0, MCA_MPOOL_FLAGS_CACHE_BYPASS, &user_out);
    else
        alloc_ptr = (ompi_free_list_memory_t*)malloc(alloc_size);

    if(NULL == alloc_ptr)
        return OMPI_ERR_TEMP_OUT_OF_RESOURCE;

    /* make the alloc_ptr a list item, save the chunk in the allocations list, and
       have ptr point to memory right after the list item structure */
    OBJ_CONSTRUCT(alloc_ptr, ompi_free_list_memory_t);
    opal_list_append(&(flist->fl_allocations), (opal_list_item_t*) alloc_ptr);

    alloc_ptr->registration = user_out;

    ptr = (unsigned char*) alloc_ptr + sizeof(ompi_free_list_memory_t);

    ptr = (unsigned char*)(align_to((size_t)ptr + flist->fl_header_space,
                flist->fl_alignment) - flist->fl_header_space);

    for(i=0; i<num_elements; i++) {
        ompi_free_list_item_t* item = (ompi_free_list_item_t*)ptr;
        item->user_data = user_out; 

        OBJ_CONSTRUCT_INTERNAL(item, flist->fl_elem_class);

        opal_atomic_lifo_push(&(flist->super), &(item->super));
        ptr += flist->fl_elem_size;
    }

    flist->fl_num_allocated += num_elements;
    return OMPI_SUCCESS;
}
int psbWsbmAllocateFromUB(uint32_t size, uint32_t align, void ** buf, void *user_pt)
{
    struct _WsbmBufferObject * wsbmBuf = NULL;
    int ret = 0;
    int offset = 0;

    ATRACE("size %d", align_to(size, 4096));

    if(!buf || !user_pt) {
        ETRACE("invalid parameter");
        return -EINVAL;
    }

    VTRACE("mainPool %p", mainPool);

    ret = wsbmGenBuffers(mainPool, 1, &wsbmBuf, align,
                        DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_CACHED |
                        WSBM_PL_FLAG_NO_EVICT | WSBM_PL_FLAG_SHARED);
    if(ret) {
        ETRACE("wsbmGenBuffers failed with error code %d", ret);
        return ret;
    }

    ret = wsbmBODataUB(wsbmBuf,
                       align_to(size, 4096), NULL, NULL, 0,
                       user_pt, -1);

    if(ret) {
        ETRACE("wsbmBOData failed with error code %d", ret);
        /*FIXME: should I unreference this buffer here?*/
        return ret;
    }

    *buf = wsbmBuf;

    VTRACE("ttm UB buffer allocated. %p", *buf);
    return 0;
}
Esempio n. 7
0
extern "C" CDECL void
debug_opaque(type_desc *t, uint8_t *front) {
    rust_task *task = rust_get_current_task();
    LOG(task, stdlib, "debug_opaque");
    debug_tydesc_helper(t);
    // Account for alignment. `front` may not indeed be the
    // front byte of the passed-in argument
    if (((uintptr_t)front % t->align) != 0) {
        front = (uint8_t *)align_to((uintptr_t)front, (size_t)t->align);
    }
    for (uintptr_t i = 0; i < t->size; ++front, ++i) {
        LOG(task, stdlib, "  byte %" PRIdPTR ": 0x%" PRIx8, i, *front);
    }
}
int psbWsbmAllocateTTMBuffer(uint32_t size, uint32_t align, void ** buf)
{
    struct _WsbmBufferObject * wsbmBuf = NULL;
    int ret = 0;
    int offset = 0;

    ATRACE("size %d", align_to(size, 4096));

    if(!buf) {
        ETRACE("invalid parameter");
        return -EINVAL;
    }

    VTRACE("mainPool %p", mainPool);

    ret = wsbmGenBuffers(mainPool, 1, &wsbmBuf, align,
                        (WSBM_PL_FLAG_VRAM | WSBM_PL_FLAG_TT |
                         WSBM_PL_FLAG_SHARED | WSBM_PL_FLAG_NO_EVICT));
    if(ret) {
        ETRACE("wsbmGenBuffers failed with error code %d", ret);
        return ret;
    }

    ret = wsbmBOData(wsbmBuf, align_to(size, 4096), NULL, NULL, 0);
    if(ret) {
        ETRACE("wsbmBOData failed with error code %d", ret);
        /*FIXME: should I unreference this buffer here?*/
        return ret;
    }

    /* wsbmBOReference(wsbmBuf); */ /* no need to add reference */

    *buf = wsbmBuf;

    VTRACE("ttm buffer allocated. %p", *buf);
    return 0;
}
Esempio n. 9
0
/* This function is not protected. It should be never used when the
 * process s still active. It was designed for debugger, in order
 * to provide them with a fast mechanism to look into the queues
 * (mostly the MPI request queue).
 */
int ompi_free_list_parse( ompi_free_list_t* list,
                          struct ompi_free_list_pos_t* position,
                          opal_list_item_t** return_item )
{
    /* Make sure we are in one of the free list allocations */
    if( NULL == position->last_memory ) {
        position->last_memory = (unsigned char*)opal_list_get_first( &(list->fl_allocations) );
        position->last_item = NULL;
    }

 dig_for_the_requests:
    /* If the request will be the first on this memory region, it's easy. */
    if( NULL == position->last_item ) {
        unsigned long ptr = (unsigned long)position->last_memory;

        ptr += sizeof(ompi_free_list_memory_t);

        ptr = align_to(ptr + list->fl_header_space, list->fl_alignment) -
            list->fl_header_space;
        *return_item = (opal_list_item_t*)ptr;
        return 0;
    }
    /* else go to the next request */
    position->last_item += list->fl_elem_size;

    {
        /* otherwise go to the next one. Once there make sure we're still on the
         * memory fragment, otherwise go to the next fragment.
         */
        size_t frag_length = (list->fl_elem_size * list->fl_num_per_alloc + 
                              + sizeof(ompi_free_list_memory_t) +
                              list->fl_header_space + list->fl_alignment);

        if( position->last_item < (position->last_memory + frag_length) ) {
            *return_item = (opal_list_item_t*)position->last_item;
            return 0;
        }
    }

    /* we're outside the fragment. Try to go to the next one ... */
    if( opal_list_get_end(&(list->fl_allocations)) ==
        ((opal_list_item_t*)position->last_memory)->opal_list_next ) {
        *return_item = NULL;
        return 0;  /* nothing anymore */
    }

    position->last_memory = (unsigned char*)((opal_list_item_t*)position->last_memory)->opal_list_next;
    goto dig_for_the_requests;
}
Esempio n. 10
0
                U* allocate(size_t size, size_t align = alignof(U))
                {
                    align = std::min(align, alignof(size_t));

                    size_t size_bytes = size*sizeof(U);
                    char* ptr = align_to(_mem+_pos+2*sizeof(size_t), align);

                    if (ptr+size_bytes > _mem+_size)
                        return nullptr;

                    prev_pos(ptr) = _pos;
                    ptr_size(ptr) = size;

                    _pos = size_t(ptr-_mem)+size_bytes;
                    return (U*)ptr;
                }
bool IntelHWComposerDrm::setupDrmFb(int disp,
                                    uint32_t fb_handler,
                                    drmModeModeInfoPtr mode)
{
    if (mDrmFd < 0) {
        ALOGE("%s: invalid drm FD\n", __func__);
        return false;
    }

    if (!mode) {
        ALOGW("%s: invalid mode !\n", __func__);
        return false;
    }

    int width = mode->hdisplay;
    int height = mode->vdisplay;
    int stride = align_to(width*4, 64);
    uint32_t fb_id = 0;

    // Drm add FB
    int ret = drmModeAddFB(mDrmFd, width, height, 24, 32,
                  stride, (uint32_t)(fb_handler), &fb_id);
    if (ret) {
        ALOGE("%s: Failed to add fb !", __func__);
        return false;
    }

    // add to local output structure
    drmModeFBPtr fbInfo = drmModeGetFB(mDrmFd, fb_id);
    if (!fbInfo) {
        ALOGE("%s: Failed to get fbInfo! ", __func__);
        return false;
    }
    setOutputFBInfo(disp, fbInfo);
    drmModeFreeFB(fbInfo);

    return true;
}
Esempio n. 12
0
matrix_t aligned_to(matrix_t *source, coord_t alignment) {
  return new_matrix(align_to(source->width, alignment),
      align_to(source->height, alignment));
}
Esempio n. 13
0
int CALLBACK
WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR command_line, int show_code)
{
    static Bank s_stack = {0};
    static Bank s_storage = {0};
    static Core s_core = {0};
    static Bitmap s_canvas = {0};
    WNDCLASSA window_class = {0};
    u32 *window_buffer = NULL;
    BITMAPINFO window_bmi = {0};


    if (align_to(CANVAS_WIDTH, 16) != CANVAS_WIDTH) {
        printf("CANVAS_WIDTH must be aligned to 16.\n");
        return 1;
    }


    CORE = &s_core;
    CORE->running = 1;
    CORE->stack = &s_stack;
    CORE->storage = &s_storage;

    bank_init(CORE->stack, STACK_CAPACITY);
    bank_init(CORE->storage, STORAGE_CAPACITY);

    // TODO: Push canvas to storage? Storage is not initialized yet, so we cannot push it there.
    CORE->canvas = &s_canvas;
    bitmap_init(CORE->canvas, CANVAS_WIDTH, CANVAS_HEIGHT, 0, 0);
    bitmap_clear(CORE->canvas, COLOR_TRANSPARENT);

    clip_reset();

    CORE->audio_volume = PUNP_SOUND_DEFAULT_MASTER_VOLUME;

    //
    //
    //

    punp_win32_instance = instance;
    QueryPerformanceFrequency((LARGE_INTEGER *)&punp_win32_perf_counter_frequency);

    // b32 sleep_is_granular = (timeBeginPeriod(1 /*ms*/) == TIMERR_NOERROR);

#ifndef RELEASE_BUILD
    printf("Debug build...");
    if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
        freopen("CONOUT$", "w", stdout);
        freopen("CONOUT$", "w", stderr);
    }
#else
    printf("Release build...");
#endif

    window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    window_class.lpfnWndProc = win32_window_callback;
    window_class.hInstance = punp_win32_instance;
    // window_class.hIcon = (HICON)LoadImage(0, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED);
    window_class.hIcon = (HICON)LoadIcon(instance, "icon.ico");
    window_class.hCursor = LoadCursor(0, IDC_ARROW);
    window_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    window_class.lpszClassName = "Punity";

    if (!RegisterClassA(&window_class)) {
        printf("RegisterClassA failed.\n");
        return 1;
    }

    {
        int screen_width = GetSystemMetrics(SM_CXSCREEN);
        int screen_height = GetSystemMetrics(SM_CYSCREEN);
        RECT rc;
        DWORD style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;

        rc.left = (screen_width - (PUNP_WINDOW_WIDTH)) / 2;
        rc.top = (screen_height - (PUNP_WINDOW_HEIGHT)) / 2;
        rc.right = rc.left + PUNP_WINDOW_WIDTH;
        rc.bottom = rc.top + PUNP_WINDOW_HEIGHT;


        ASSERT(AdjustWindowRect(&rc, style, FALSE) != 0);

        // int window_width  = rc.right - rc.left;
        // int window_height = rc.bottom - rc.top;
        // rc.left = (screen_width  - width) / 2;
        // rc.top  = (screen_height - height) / 2;

        punp_win32_window = CreateWindowExA(
                0,
                window_class.lpszClassName,
                WINDOW_TITLE,
                style,
                rc.left, rc.top,
                rc.right - rc.left, rc.bottom - rc.top,
                0, 0,
                punp_win32_instance,
                0);
    }
    if (!punp_win32_window) {
        printf("CreateWindowExA failed.\n");
        return 1;
    }

    // Canvas
    window_bmi.bmiHeader.biSize = sizeof(window_bmi.bmiHeader);
    window_bmi.bmiHeader.biWidth = CANVAS_WIDTH;
    window_bmi.bmiHeader.biHeight = CANVAS_HEIGHT;
    window_bmi.bmiHeader.biPlanes = 1;
    window_bmi.bmiHeader.biBitCount = 32;
    window_bmi.bmiHeader.biCompression = BI_RGB;

    window_buffer = (u32 *)bank_push(CORE->stack, (CANVAS_WIDTH * 4) * CANVAS_HEIGHT);
    ASSERT(window_buffer);

    // Sound

    if (punp_win32_sound_init() == 0) {
        punp_win32_audio_buffer = 0;
    }


    init();


    // TODO: Center window
    ShowWindow(punp_win32_window, SW_SHOW);

    {
        f64 frame_time_stamp, frame_time_now, frame_time_delta;
        int x, y;
        u32 *window_row;
        u8 *canvas_it;
        MSG message;
        perf_from(&CORE->perf_frame);
        while (CORE->running) {
            perf_to(&CORE->perf_frame);
            perf_from(&CORE->perf_frame_inner);

            memset(&CORE->key_deltas, 0, KEYS_MAX);

            while (PeekMessage(&message, 0, 0, 0, PM_REMOVE)) {
                if (message.message == WM_QUIT) {
                    CORE->running = 0;
                }

                TranslateMessage(&message);
                DispatchMessageA(&message);
            }

            perf_from(&CORE->perf_step);
            step();
            perf_to(&CORE->perf_step);

            perf_from(&CORE->perf_audio);
            if (punp_win32_audio_buffer) {
                punp_win32_sound_step();
            }
            perf_to(&CORE->perf_audio);

            perf_from(&CORE->perf_blit);
            perf_from(&CORE->perf_blit_cvt);
            canvas_it = CORE->canvas->pixels;
            for (y = CANVAS_HEIGHT; y != 0; --y) {
                window_row = window_buffer + ((y - 1) * CANVAS_WIDTH);
                for (x = 0; x != CANVAS_WIDTH; ++x) {
                    *(window_row++) = CORE->palette.colors[*canvas_it++].rgba;
                }
            }
            perf_to(&CORE->perf_blit_cvt);

            perf_from(&CORE->perf_blit_gdi);
            {
                HDC dc = GetDC(punp_win32_window);
        #if 1
                // TODO: This is sadly slow (50us on my machine), need to find a faster way to do this.
                StretchDIBits(dc,
                              0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
                              0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
                              window_buffer,
                              &window_bmi,
                              DIB_RGB_COLORS,
                              SRCCOPY);
        #else
        #endif
                ReleaseDC(punp_win32_window, dc);
            }
            perf_to(&CORE->perf_blit_gdi);
            perf_to(&CORE->perf_blit);

            perf_to(&CORE->perf_frame_inner);

            {
                f32 frame_delta = perf_delta(&CORE->perf_frame);
                if (frame_delta < PUNP_FRAME_TIME) {
                    // printf("sleeping ... %.3f\n", (f32)PUNP_FRAME_TIME - frame_delta);
                    Sleep((PUNP_FRAME_TIME - frame_delta) * 1e3);
                }
            }
            CORE->frame++;

    #if 0
            printf("stack %d storage %d\n",
                   CORE->stack->it - CORE->stack->begin,
                   CORE->storage->it - CORE->storage->begin);
    #endif
        }
    }

#if PUNP_SOUND_DEBUG_FILE
    fclose(punp_audio_buf_file);
#endif

    return 0;
}
bool IntelDisplayDevice::updateLayersData(hwc_display_contents_1_t *list)
{
    IntelDisplayPlane *plane = 0;
    bool ret = true;
    bool handled = true;

    mYUVOverlay = -1;

    if (!list)
	return false;

    for (size_t i=0 ; i<(size_t)mLayerList->getLayersCount(); i++) {
        hwc_layer_1_t *layer = &list->hwLayers[i];
        // layer safety check
        if (!isHWCLayer(layer) || !layer)
            continue;

        IMG_native_handle_t *grallocHandle =
            (IMG_native_handle_t*)layer->handle;

        // check plane
        plane = mLayerList->getPlane(i);
        if (!plane)
            continue;

        // get layer parameter
        int bobDeinterlace;
        int srcX = layer->sourceCrop.left;
        int srcY = layer->sourceCrop.top;
        int srcWidth = layer->sourceCrop.right - layer->sourceCrop.left;
        int srcHeight = layer->sourceCrop.bottom - layer->sourceCrop.top;
        int planeType = plane->getPlaneType();

        if(srcHeight == 1 || srcWidth == 1) {
            mLayerList->detachPlane(i, plane);
            layer->compositionType = HWC_FRAMEBUFFER;
            handled = false;
            continue;
        }
        if (planeType == IntelDisplayPlane::DISPLAY_PLANE_OVERLAY) {
            if (mDrm->isOverlayOff()) {
                plane->disable();
                handled = false;
                layer->compositionType = HWC_FRAMEBUFFER;
                continue;
            }
        }

        // get & setup data buffer and buffer format
        IntelDisplayBuffer *buffer = plane->getDataBuffer();
        IntelDisplayDataBuffer *dataBuffer =
            reinterpret_cast<IntelDisplayDataBuffer*>(buffer);
        if (!dataBuffer) {
            ALOGE("%s: invalid data buffer\n", __func__);
            continue;
        }

        int bufferWidth = grallocHandle->iWidth;
        int bufferHeight = grallocHandle->iHeight;
        uint32_t bufferHandle = grallocHandle->fd[0];
        int format = grallocHandle->iFormat;
        uint32_t transform = layer->transform;

        if (planeType == IntelDisplayPlane::DISPLAY_PLANE_OVERLAY) {
            int flags = mLayerList->getFlags(i);
            if (flags & IntelDisplayPlane::DELAY_DISABLE) {
                ALOGD_IF(ALLOW_HWC_PRINT,
                       "updateLayerData: disable plane (DELAY)!");
                flags &= ~IntelDisplayPlane::DELAY_DISABLE;
                mLayerList->setFlags(i, flags);
                plane->disable();
            }
            //FIXME: is a workaround
            // Bypass overlay layer, if
            // device is rotated
            // and not presentation mode
            // and video is not only attached to HDMI
            if (list && (list->flags & HWC_ROTATION_IN_PROGRESS) &&
                    (mDrm->getDisplayMode() == OVERLAY_EXTEND &&
                     !mDrm->isPresentationMode() && !mDrm->onlyHdmiHasVideo())) {
                ALOGI_IF(ALLOW_HWC_PRINT, "Bypass overlay layer");
                mLayerList->detachPlane(i, plane);
                layer->compositionType = HWC_OVERLAY;
                handled = false;
                continue;
            }

            // check if can switch to overlay
            bool useOverlay = useOverlayRotation(layer, i,
                                                 bufferHandle,
                                                 bufferWidth,
                                                 bufferHeight,
                                                 srcX,
                                                 srcY,
                                                 srcWidth,
                                                 srcHeight,
                                                 transform);

            if (!useOverlay) {
                ALOGD_IF(ALLOW_HWC_PRINT,
                       "updateLayerData: useOverlayRotation failed!");
                if (!mLayerList->getForceOverlay(i)) {
                    ALOGD_IF(ALLOW_HWC_PRINT,
                           "updateLayerData: fallback to ST to do rendering!");
                    // fallback to ST to render this frame
                    layer->compositionType = HWC_FRAMEBUFFER;
                    mForceSwapBuffer = true;
                    handled = false;
                }
                // disable overlay when rotated buffer is not ready
                flags |= IntelDisplayPlane::DELAY_DISABLE;
                mLayerList->setFlags(i, flags);
                continue;
            }

            bobDeinterlace = isBobDeinterlace(layer);
            if (bobDeinterlace) {
                flags |= IntelDisplayPlane::BOB_DEINTERLACE;
            } else {
                flags &= ~IntelDisplayPlane::BOB_DEINTERLACE;
            }
            mLayerList->setFlags(i, flags);

            // switch to overlay
            layer->compositionType = HWC_OVERLAY;

            // transformed buffer not from gralloc, can't use it's stride directly
            uint32_t grallocStride = !transform ? grallocHandle->iStride : align_to(bufferWidth, 32);
            int format = grallocHandle->iFormat;

            dataBuffer->setFormat(format);
            dataBuffer->setStride(grallocStride);
            dataBuffer->setWidth(bufferWidth);
            dataBuffer->setHeight(bufferHeight);
            dataBuffer->setCrop(srcX, srcY, srcWidth, srcHeight);
            dataBuffer->setDeinterlaceType(bobDeinterlace);
            // set the data buffer back to plane
            ret = ((IntelOverlayPlane*)plane)->setDataBuffer(bufferHandle,
                                                             transform,
                                                             grallocHandle);
            if (!ret) {
                ALOGE("%s: failed to update overlay data buffer\n", __func__);
                mLayerList->detachPlane(i, plane);
                layer->compositionType = HWC_FRAMEBUFFER;
                handled = false;
            }
            if (layer->compositionType == HWC_OVERLAY &&
                format == HAL_PIXEL_FORMAT_INTEL_HWC_NV12)
                mYUVOverlay = i;
        } else if (planeType == IntelDisplayPlane::DISPLAY_PLANE_RGB_OVERLAY) {
            IntelRGBOverlayPlane *rgbOverlayPlane =
                reinterpret_cast<IntelRGBOverlayPlane*>(plane);
            uint32_t yuvBufferHandle =
                rgbOverlayPlane->convert((uint32_t)grallocHandle,
                                          srcWidth, srcHeight,
                                          srcX, srcY);
            if (!yuvBufferHandle) {
                LOGE("updateLayersData: failed to convert\n");
                continue;
            }

            grallocHandle = (IMG_native_handle_t*)yuvBufferHandle;
            bufferWidth = grallocHandle->iWidth;
            bufferHeight = grallocHandle->iHeight;
            bufferHandle = grallocHandle->fd[0];
            format = grallocHandle->iFormat;

            uint32_t grallocStride = grallocHandle->iStride;

            dataBuffer->setFormat(format);
            dataBuffer->setStride(grallocStride);
            dataBuffer->setWidth(bufferWidth);
            dataBuffer->setHeight(bufferHeight);
            dataBuffer->setCrop(srcX, srcY, srcWidth, srcHeight);
            dataBuffer->setDeinterlaceType(0);

            // set the data buffer back to plane
            ret = rgbOverlayPlane->setDataBuffer(bufferHandle,
                                                 0, grallocHandle);
            if (!ret) {
                LOGE("%s: failed to update overlay data buffer\n", __func__);
                mLayerList->detachPlane(i, plane);
                layer->compositionType = HWC_FRAMEBUFFER;
                handled = false;
            }
        } else if (planeType == IntelDisplayPlane::DISPLAY_PLANE_SPRITE ||
                   planeType == IntelDisplayPlane::DISPLAY_PLANE_PRIMARY) {

            // adjust the buffer format if no blending is needed
            // some test cases would fail due to a weird format!
            if (layer->blending == HWC_BLENDING_NONE) {
                switch (format) {
                case HAL_PIXEL_FORMAT_BGRA_8888:
                    format = HAL_PIXEL_FORMAT_BGRX_8888;
                    break;
                case HAL_PIXEL_FORMAT_RGBA_8888:
                    format = HAL_PIXEL_FORMAT_RGBX_8888;
                    break;
                }
            }

            // set data buffer format
            dataBuffer->setFormat(format);
            dataBuffer->setWidth(bufferWidth);
            dataBuffer->setHeight(bufferHeight);
            dataBuffer->setCrop(srcX, srcY, srcWidth, srcHeight);
            // set the data buffer back to plane
            ret = plane->setDataBuffer(bufferHandle, transform, grallocHandle);
            if (!ret) {
                ALOGE("%s: failed to update sprite data buffer\n", __func__);
                mLayerList->detachPlane(i, plane);
                layer->compositionType = HWC_FRAMEBUFFER;
                handled = false;
            }
        } else {
            ALOGW("%s: invalid plane type %d\n", __func__, planeType);
            continue;
        }

        // clear layer's visible region if need clear up flag was set
        // and sprite plane was used as primary plane (point to FB)
        if (mLayerList->getNeedClearup(i) &&
            mPlaneManager->primaryAvailable(0)) {
            ALOGD_IF(ALLOW_HWC_PRINT,
                  "updateLayersData: clear visible region of layer %d", i);
            list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;
        }
    }

    return handled;
}
bool IntelDisplayDevice::flipFramebufferContexts(void *contexts,
                                          hwc_layer_1_t *layer)
{
    intel_sprite_context_t *context;
    mdfld_plane_contexts_t *planeContexts;
    int zOrderConfig;
    bool forceBottom = false;

    ALOGD_IF(ALLOW_HWC_PRINT, "flipFrameBufferContexts");

    if (!contexts) {
        ALOGE("%s: Invalid plane contexts\n", __func__);
        return false;
    }

    IMG_native_handle_t *grallocHandle =
                 (IMG_native_handle_t*)layer->handle;

    if (!grallocHandle)
        return false;

    IntelDisplayBuffer *buffer = NULL;

    for (int i = 0; i < NUM_FB_BUFFERS; i++) {
        if (mFBBuffers[i].ui64Stamp == grallocHandle->ui64Stamp) {
            ALOGD_IF(ALLOW_HWC_PRINT,
                     "%s: buf stamp %lld...\n", __func__,grallocHandle->ui64Stamp);
            buffer = mFBBuffers[i].buffer;
            break;
        }
    }

    if (!buffer) {
        // release the buffer in the next slot
        if (mFBBuffers[mNextBuffer].ui64Stamp ||
                    mFBBuffers[mNextBuffer].buffer) {
            mGrallocBufferManager->unmap(mFBBuffers[mNextBuffer].buffer);
            mFBBuffers[mNextBuffer].ui64Stamp = 0;
            mFBBuffers[mNextBuffer].buffer = 0;
        }

        buffer = mGrallocBufferManager->map(grallocHandle->fd[0]);

        if (!buffer) {
            ALOGE("%s: failed to map HDMI handle !\n", __func__);
            return false;
        }

        mFBBuffers[mNextBuffer].ui64Stamp = grallocHandle->ui64Stamp;
        mFBBuffers[mNextBuffer].buffer = buffer;
        // move mNextBuffer pointer
        mNextBuffer = (mNextBuffer + 1) % NUM_FB_BUFFERS;
    }

    planeContexts = (mdfld_plane_contexts_t*)contexts;

    uint32_t gttOffsetInPage = buffer->getGttOffsetInPage();

    // update layer info;
    uint32_t fbWidth = layer->sourceCrop.right;
    uint32_t fbHeight = layer->sourceCrop.bottom;

    context = &planeContexts->sprite_contexts[mDisplayIndex];
    context->update_mask = SPRITE_UPDATE_ALL;
    context->index = mDisplayIndex;
    context->pipe = mDisplayIndex;
    context->linoff = 0;

    context->stride = align_to((4 * fbWidth), 128);
    context->pos = 0;
    context->size = ((fbHeight - 1) & 0xfff) << 16 | ((fbWidth - 1) & 0xfff);
    context->surf = gttOffsetInPage << 12;

    // config z order; switch z order may cause flicker
    zOrderConfig = mPlaneManager->getZOrderConfig(mDisplayIndex);
    if ((zOrderConfig == IntelDisplayPlaneManager::ZORDER_OcOaP) ||
        (zOrderConfig == IntelDisplayPlaneManager::ZORDER_OaOcP))
        forceBottom = true;

    // if RGB layer is bottom, force fb to be bottom and bgrx format
    // to solve blank screen of some 3D applications with premulti alpha.
    if (forceBottom) {
        context->cntr = INTEL_SPRITE_PIXEL_FORMAT_BGRX8888;
        context->cntr |= INTEL_SPRITE_FORCE_BOTTOM;
    } else if (mLayerList->getAttachedPlanesCount() == 0) {
        context->cntr = INTEL_SPRITE_PIXEL_FORMAT_BGRX8888;
    }
    else {
        context->cntr = INTEL_SPRITE_PIXEL_FORMAT_BGRA8888;
    }
    context->cntr |= 0x80000000;

    // update active sprite
    planeContexts->active_sprites |= (1 << mDisplayIndex);

    return true;
}
BufferMapper* OverlayPlaneBase::getTTMMapper(BufferMapper& grallocMapper, struct VideoPayloadBuffer *payload)
{
    buffer_handle_t khandle;
    uint32_t w, h;
    uint32_t yStride, uvStride;
    stride_t stride;
    int srcX, srcY, srcW, srcH;
    int tmp;

    DataBuffer *buf;
    ssize_t index;
    TTMBufferMapper *mapper;
    bool ret;

    if (!payload) {
        ETRACE("invalid payload buffer");
        return 0;
    }

    srcX = grallocMapper.getCrop().x;
    srcY = grallocMapper.getCrop().y;
    srcW = grallocMapper.getCrop().w;
    srcH = grallocMapper.getCrop().h;

    // init ttm buffer
    if (mUseScaledBuffer) {
        khandle = payload->scaling_khandle;
    } else {
        khandle = payload->rotated_buffer_handle;
    }
    index = mTTMBuffers.indexOfKey(khandle);
    if (index < 0) {
        VTRACE("unmapped TTM buffer, will map it");

        if (mUseScaledBuffer) {
            w = payload->scaling_width;
            h = payload->scaling_height;
        } else {
            w = payload->rotated_width;
            h = payload->rotated_height;

            checkCrop(srcX, srcY, srcW, srcH, payload->coded_width, payload->coded_height);
        }

        uint32_t format = grallocMapper.getFormat();
        // this is for sw decode with tiled buffer in landscape mode
        if (payload->tiling)
            format = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled;

        // calculate stride
        switch (format) {
        case HAL_PIXEL_FORMAT_YV12:
        case HAL_PIXEL_FORMAT_I420:
            uint32_t yStride_align;
            yStride_align = DisplayQuery::getOverlayLumaStrideAlignment(grallocMapper.getFormat());
            if (yStride_align > 0)
            {
                yStride = align_to(align_to(w, 32), yStride_align);
            }
            else
            {
                yStride = align_to(align_to(w, 32), 64);
            }
            uvStride = align_to(yStride >> 1, 64);
            stride.yuv.yStride = yStride;
            stride.yuv.uvStride = uvStride;
            break;
        case HAL_PIXEL_FORMAT_NV12:
            yStride = align_to(align_to(w, 32), 64);
            uvStride = yStride;
            stride.yuv.yStride = yStride;
            stride.yuv.uvStride = uvStride;
            break;
        case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
        case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
            if (mUseScaledBuffer) {
                stride.yuv.yStride = payload->scaling_luma_stride;
                stride.yuv.uvStride = payload->scaling_chroma_u_stride;
            } else {
               yStride = align_to(align_to(w, 32), 64);
               uvStride = yStride;
               stride.yuv.yStride = yStride;
               stride.yuv.uvStride = uvStride;
            }
            break;
        case HAL_PIXEL_FORMAT_YUY2:
        case HAL_PIXEL_FORMAT_UYVY:
            yStride = align_to((align_to(w, 32) << 1), 64);
            uvStride = 0;
            stride.yuv.yStride = yStride;
            stride.yuv.uvStride = uvStride;
            break;
        }

        DataBuffer buf(khandle);
        // update buffer
        buf.setStride(stride);
        buf.setWidth(w);
        buf.setHeight(h);
        buf.setCrop(srcX, srcY, srcW, srcH);
        buf.setFormat(format);

        // create buffer mapper
        bool res = false;
        do {
            mapper = new TTMBufferMapper(*mWsbm, buf);
            if (!mapper) {
                ETRACE("failed to allocate mapper");
                break;
            }
            // map ttm buffer
            ret = mapper->map();
            if (!ret) {
                ETRACE("failed to map");
                invalidateTTMBuffers();
                ret = mapper->map();
                if (!ret) {
                    ETRACE("failed to remap");
                    break;
                }
            }

            if (mTTMBuffers.size() >= OVERLAY_DATA_BUFFER_COUNT) {
                invalidateTTMBuffers();
            }

            // add mapper
            index = mTTMBuffers.add(khandle, mapper);
            if (index < 0) {
                ETRACE("failed to add TTMMapper");
                break;
            }

            // increase mapper refCount since it is added to mTTMBuffers
            mapper->incRef();
            res = true;
        } while (0);

        if (!res) {
            // error handling
            if (mapper) {
                mapper->unmap();
                delete mapper;
                mapper = NULL;
            }
            return 0;
        }
    } else {
bool IntelHWComposer::handleHotplugEvent(int hpd, void *data)
{
    bool ret = false;

    ALOGD_IF(ALLOW_HWC_PRINT, "handleHotplugEvent");

    if (!mDrm) {
        ALOGW("%s: mDrm is not intialized!\n", __func__);
        return false;
    }

    if (hpd) {
        // get display mode
        intel_display_mode_t *s_mode = (intel_display_mode_t *)data;
        drmModeModeInfoPtr mode;
        mode = mDrm->selectDisplayDrmMode(OUTPUT_HDMI, s_mode);
        if (!mode)
            return false;

        // alloc buffer;
        mHDMIFBHandle.size = mode->vdisplay * align_to(mode->hdisplay * 4, 64);
        ret = mGrallocBufferManager->alloc(mHDMIFBHandle.size,
                                      &mHDMIFBHandle.umhandle,
                                      &mHDMIFBHandle.kmhandle);
        if (!ret)
            return false;

        // mode setting;
        ret = mDrm->setDisplayDrmMode(OUTPUT_HDMI, mHDMIFBHandle.kmhandle, mode);
        if (!ret)
            return false;

        ALOGD("%s: detected hdmi hotplug event:%s\n", __func__, hpd?"IN":"OUT");
        handleDisplayModeChange();

        /* hwc_dev->procs is set right after the device is opened, but there is
         * still a race condition where a hotplug event might occur after the open
         * but before the procs are registered. */
        if (mProcs && mProcs->vsync) {
            mProcs->hotplug(mProcs, HWC_DISPLAY_EXTERNAL, hpd);
        }
    } else {
        ret = mDrm->handleDisplayDisConnection(OUTPUT_HDMI);
        if (!ret)
            return false;

        ALOGD("%s: detected hdmi hotplug event:%s\n", __func__, hpd?"IN":"OUT");
        handleDisplayModeChange();

        /* hwc_dev->procs is set right after the device is opened, but there is
         * still a race condition where a hotplug event might occur after the open
         * but before the procs are registered. */
        if (mProcs && mProcs->vsync) {
            mProcs->hotplug(mProcs, HWC_DISPLAY_EXTERNAL, hpd);
        }
        // TODO: here we need to wait for the plug-out take effect.
        waitForHpdCompletion();
        // rm FB
        mDrm->deleteDrmFb(OUTPUT_HDMI);
        // release buffer;
        ret = mGrallocBufferManager->dealloc(mHDMIFBHandle.umhandle);
        if (!ret)
            return false;

        memset(&mHDMIFBHandle, 0, sizeof(mHDMIFBHandle));
    }
    return true;
}