Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15530441
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: 嵌入式

2009-07-12 09:15:15

浅析CreateCompatibleDC如何仅仅malloc一块含有lcd有效信息的纯内存区作为surface->pixels的

m_hdc = CreateCompatibleDC(HDC_SCREEN);

HDC_SCREEN只是表示创建的pdc对应的surface将含有有效lcd信息数值,而不是自己传入的depth等数值.
即:
surface->video = current_video;
surface->format = GAL_AllocFormat(screen->format->BitsPerPixel,
                                screen->format->Rmask,
                                screen->format->Gmask,
                                screen->format->Bmask,
                                screen->format->Amask);
surface->pixels = malloc(surface->h*surface->pitch);
通过malloc从pc或arm的DDR中申请的一块纯内存空间.

所以CreateCompatibleDC(HDC_SCREEN);
仅仅是malloc一块含有lcd有效信息的纯内存区作为surface->pixels内存数据区地址[luther.gliethttp]
#define CreateCompatibleDC(hdc) CreateCompatibleDCEx(hdc, 0, 0);
HDC GUIAPI CreateCompatibleDCEx (HDC hdc, int width, int height)
{
    PDC pdc;
    PDC pmem_dc = NULL;
    GAL_Surface* surface;
    DWORD flags;
/*
static inline PDC dc_HDC2PDC (HDC hdc)
{
    if (hdc == HDC_SCREEN) return &__mg_screen_dc;
    return (PDC) hdc;
} */
    pdc = dc_HDC2PDC (hdc); // 返回__mg_screen_dc,

    if (!(pmem_dc = malloc (sizeof(DC))))
        return HDC_INVALID;

    if (width <= 0 || height <= 0) {
//dc_InitScreenDC函数中做了如下初始化[luther.gliethttp]
//    pdc->DevRC.left = 0; // 左上角
//    pdc->DevRC.top  = 0;
//    pdc->DevRC.right = surface->w;
//    右下角,这样该pdc对应矩形surface,即__gal_screen的w和h,就是整个lcd屏幕的framebuffer内存区[luther.gliethttp]
//    pdc->DevRC.bottom = surface->h;
        width = RECTW (pdc->DevRC);
        height = RECTH (pdc->DevRC); // lcd屏幕的宽和高
    }
// __gal_screen->flags = (GAL_FULLSCREEN|GAL_HWSURFACE);
// __mg_screen_dc->surface 等于 __gal_screen[luther.gliethttp]
    if ((pdc->surface->flags & GAL_HWSURFACE) == GAL_HWSURFACE)
        flags = GAL_HWSURFACE; // 我们这里flags将等于GAL_HWSURFACE
    else
        flags = GAL_SWSURFACE;

    LOCK (&__mg_gdilock);
    surface = GAL_CreateRGBSurface (flags,
                    width, height,
                    pdc->surface->format->BitsPerPixel,
                    pdc->surface->format->Rmask,
                    pdc->surface->format->Gmask,
                    pdc->surface->format->Bmask,
                    pdc->surface->format->Amask);
    UNLOCK (&__mg_gdilock);

    if (!surface) {
        free (pmem_dc);
        return HDC_INVALID;
    }

    /* Set surface attributes */
    if (pdc->surface->format->BitsPerPixel <= 8) {
        GAL_SetPalette (surface, GAL_LOGPAL,
            (GAL_Color*) pdc->surface->format->palette->colors,
            0, 1<surface->format->BitsPerPixel);
    }

    if (pdc->surface->flags & GAL_SRCALPHA) {
        GAL_SetAlpha (surface, GAL_SRCALPHA,
                    pdc->surface->format->alpha);
    }

    if (pdc->surface->flags & GAL_SRCCOLORKEY) {
        GAL_SetColorKey (surface, GAL_SRCCOLORKEY,
                pdc->surface->format->colorkey);
    }

    pmem_dc->DataType = TYPE_HDC; // 数据类型
    pmem_dc->DCType   = TYPE_MEMDC; // 类型
    pmem_dc->inuse = TRUE;
    pmem_dc->surface = surface;

    pmem_dc->DevRC.left = 0;
    pmem_dc->DevRC.top  = 0;
    pmem_dc->DevRC.right = width;
    pmem_dc->DevRC.bottom = height; // 该dc使用malloc申请到的内存对应的矩形.
// 这里就是整个LCD屏幕

    dc_InitMemDCFrom (pmem_dc, pdc);

    /* clip region info */
    pmem_dc->pGCRInfo = NULL;
    pmem_dc->oldage = 0;
    InitClipRgn (&pmem_dc->ecrgn, &__mg_FreeClipRectList);
    SetClipRgn (&pmem_dc->ecrgn, &pmem_dc->DevRC);
    
    return (HDC)pmem_dc;
}

/*
 * Create an empty RGB surface of the appropriate depth
 */
GAL_Surface * GAL_CreateRGBSurface (Uint32 flags,
            int width, int height, int depth,
            Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
    GAL_VideoDevice *video = current_video;
    GAL_VideoDevice *this  = current_video;
    GAL_Surface *screen;
    GAL_Surface *surface;

    /* Check to see if we desire the surface in video memory */
    if ( video ) {
        screen = GAL_PublicSurface; // 这时screen = __gal_screen;
    } else {
        screen = NULL;
    }
    if ( screen && ((screen->flags&GAL_HWSURFACE) == GAL_HWSURFACE) ) {
        if ( (flags&(GAL_SRCCOLORKEY|GAL_SRCALPHA)) != 0 ) { // pass
            flags |= GAL_HWSURFACE;
        }
        if ( (flags & GAL_SRCCOLORKEY) == GAL_SRCCOLORKEY ) { // pass
            if ( ! current_video->info.blit_hw_CC ) {
                flags &= ~GAL_HWSURFACE;
            }
        }
        if ( (flags & GAL_SRCALPHA) == GAL_SRCALPHA ) { // pass
            if ( ! current_video->info.blit_hw_A ) {
                flags &= ~GAL_HWSURFACE;
            }
        }
    } else {
        flags &= ~GAL_HWSURFACE;
    }

    /* Allocate the surface */
    surface = (GAL_Surface *)malloc(sizeof(*surface));
    if ( surface == NULL ) {
        GAL_OutOfMemory();
        return(NULL);
    }
    if ((flags & GAL_HWSURFACE) == GAL_HWSURFACE)
        surface->video = current_video; // 该surface有物理video[luther.gliethttp]
    else
        surface->video = NULL;

    surface->flags = GAL_SWSURFACE; // 将需要建立的surface->flags强制变为GAL_SWSURFACE软surface区块

    if ( (flags & GAL_HWSURFACE) == GAL_HWSURFACE ) {
        // 该surface的format中含有有效的lcd物理信息,那么使用lcd有效物理数据,而非用户
        // 传入的depth等数据[luther.gliethttp]
        depth = screen->format->BitsPerPixel;
        Rmask = screen->format->Rmask;
        Gmask = screen->format->Gmask;
        Bmask = screen->format->Bmask;
        Amask = screen->format->Amask;
    }
    surface->format = GAL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
    if ( surface->format == NULL ) {
        free(surface);
        return(NULL);
    }
    if ( Amask ) {
        surface->flags |= GAL_SRCALPHA;
    }
    surface->w = width;
    surface->h = height;
    surface->pitch = GAL_CalculatePitch(surface);
    surface->pixels = NULL;
    surface->offset = 0;
    surface->hwdata = NULL;
    surface->map = NULL;
    surface->format_version = 0;
    GAL_SetClipRect(surface, NULL);

    /* Get the pixels */
    if ( ((flags&GAL_HWSURFACE) == GAL_SWSURFACE) || 
// 如果flags为GAL_HWSURFACE,即申请一个纯内存区,那么直接执行下面的malloc
                (video->AllocHWSurface(this, surface) < 0) ) {
// 如果flags为GAL_HWSURFACE,那么首先尝试从lcd驱动程序中获取一块可能有加速功能的内存块
// 如果申请失败,比如QVFB_AllocHWSurface()就直接返回-1,那么[luther.gliethttp]
// 就使用malloc从pc机或者arm的DDR中申请一块内存,作为该surface区块数据操作的
// 目的mem内存[luther.gliethttp]
        if ( surface->w && surface->h ) {
            surface->pixels = malloc(surface->h*surface->pitch);
            if ( surface->pixels == NULL ) {
                GAL_FreeSurface(surface);
                GAL_OutOfMemory();
                return(NULL);
            }
            /* This is important for bitmaps */
            memset(surface->pixels, 0, surface->h*surface->pitch);
            surface->flags &= ~GAL_HWSURFACE; // 那标识该surface的pixels是使用malloc获取的本机内存,而非lcd驱动器中物理内存.
        }
    }

    /* Allocate an empty mapping */
    surface->map = GAL_AllocBlitMap();
    if ( surface->map == NULL ) {
        GAL_FreeSurface(surface);
        return(NULL);
    }

    /* The surface is ready to go */
    surface->refcount = 1;
#ifdef CHECK_LEAKS
    ++surfaces_allocated;
#endif
    return(surface);
}
阅读(4042) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~