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; }
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; }
/// @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; }
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; }
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; }
/* 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; }
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; }
matrix_t aligned_to(matrix_t *source, coord_t alignment) { return new_matrix(align_to(source->width, alignment), align_to(source->height, alignment)); }
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; }