Performance of glReadPixels and CopyBits

Posted on Updated on

  • glReadPixels:
    30 times capture cost 542303875.000000 nanoseconds; -542303 microseconds.

    size_t bitsPerPixel = CGBitmapContextGetBitsPerPixel( context ) ;
    size_t width = CGBitmapContextGetWidth( context ) ;
    size_t height = CGBitmapContextGetHeight( context ) ;
    size_t bytewidth = CGBitmapContextGetBytesPerRow( context );

    time1 = UpTime();
    for ( i = 0 ;i
    glReadPixels( 0, 0, width, height, GL_BGRA, packedPixelFormat, data);
    time2 = UpTime();
    nanosec = AbsoluteDeltaToNanoseconds(time2,time1);
    duration = AbsoluteDeltaToDuration(time2,time1);
    nanodouble = ConvertNanosecondsToDouble ( &nanosec);
    printf(" %d times capture cost %f nanoseconds; %ld milliseconds.\n",i,nanodouble, duration);

  • CopyBits:
    30 times capture cost 3910429766.000000 nanoseconds; -3910429 microseconds.


    mainDevice = GetMainDevice();
    /* Store its current pixel depth. */
    depth = (**(**mainDevice).gdPMap).pixelSize;

    /* Make an identical copy of its pixmap's colortable. */
    cTable = (**(**mainDevice).gdPMap).pmTable;
    (void) HandToHand( (Handle*)(&cTable) );

    bytesPerRow = ((gBounds.right - gBounds.left) * depth) / 8;
    offBaseAddr = NewPtr((unsigned long)bytesPerRow * (gBounds.bottom - gBounds.top));

    gPixMap.baseAddr = offBaseAddr; /* Point to image */
    gPixMap.rowBytes = bytesPerRow | 0x8000; /* MSB set for PixMap */
    gPixMap.bounds = gBounds; /* Use given bounds */
    gPixMap.pmVersion = 0; /* No special stuff */
    gPixMap.packType = 0; /* Default PICT pack */
    gPixMap.packSize = 0; /* Always zero in mem */
    gPixMap.hRes = 72; /* 72 DPI default res */
    gPixMap.vRes = 72; /* 72 DPI default res */
    gPixMap.pixelSize = depth; /* Set # bits/pixel */
    //gPixMap.planeBytes = 0; /* Not used */
    //gPixMap.pmReserved = 0; /* Not used */

    gPixMap.pixelType = 0; /* Indicates indexed */
    gPixMap.cmpCount = 1; /* Have 1 component */
    gPixMap.cmpSize = depth; /* Component size=depth */
    gPixMap.pmTable = cTable; /* Handle to CLUT */

    startTime = UpTime();
    for (i = 0 ;i
    CopyBits( (BitMap *)*(**mainDevice).gdPMap, (BitMap *)(&gPixMap),
    &(**(**mainDevice).gdPMap).bounds, &gPixMap.bounds, srcCopy, 0l );
    endTime = UpTime();
    nano = AbsoluteDeltaToNanoseconds(endTime,startTime) ;
    duration = AbsoluteDeltaToDuration(endTime,startTime);
    nanodouble = ConvertNanosecondsToDouble ( &nano );
    printf(" %d times capture cost %f nanoseconds; %ld milliseconds.\n",i,nanodouble, duration);

run on
Hardware Overview:

Machine Name: MacBook
Machine Model: MacBook1,1
Processor Name: Intel Core Duo
Processor Speed: 1.83 GHz
Number Of Processors: 1
Total Number Of Cores: 2
L2 Cache (per processor): 2 MB
Memory: 1 GB
Bus Speed: 667 MHz
Screen Size: 1152×720, Millions

對「Performance of glReadPixels and CopyBits」的一則回應

    cotton5415 responded:
    6 十一月, 2006 於 6:15 上午

    30 times of calling CapScreenFetchdataToContext spends -539964 milliseconds
    30 times of calling CapScreenFetchdataToContextFast spends -545436 milliseconds


    int CapScreenFetchDataToContextFast(CGContextRef context, void * data, size_t width, size_t height,size_t bytewidth, GLenum packedPixelFormat )
    {
    if ( context == NULL)
    return -1;

    if ( data == NULL)
    return -2;

    glReadPixels( 0, 0, width, height,
    GL_BGRA,
    packedPixelFormat,
    data);
    }


    int CapScreenFetchDataToContext ( CGContextRef context)
    {
    if ( context == NULL)
    return -1;
    GLenum packedPixelFormat ;
    size_t bitsPerPixel = CGBitmapContextGetBitsPerPixel( context ) ;
    size_t width = CGBitmapContextGetWidth( context ) ;
    size_t height = CGBitmapContextGetHeight( context ) ;
    size_t bytewidth = CGBitmapContextGetBytesPerRow( context );
    void * data = CGBitmapContextGetData( context);
    if ( data == NULL)
    return -2;

    switch ( bitsPerPixel)
    {
    case 16:
    packedPixelFormat = GL_UNSIGNED_SHORT_5_5_5_1 ;
    break;
    case 32:
    packedPixelFormat = GL_UNSIGNED_INT_8_8_8_8 ;
    break;
    default:
    return -3;
    }

    /*
    * Fetch the data in XRGB format, matching the bitmap context.
    */
    glReadPixels( 0, 0, width, height, GL_BGRA, packedPixelFormat, data);

    /*
    * glReadPixels generates a quadrant I raster, with origin in the lower left
    * This isn't a problem for signal processing routines such as compressors,
    * as they can simply use a negative 'advance' to move between scanlines.
    * CGImageRef and CGBitmapContext assume a quadrant III raster, though, so we need to
    * invert it. Pixel reformatting can also be done here.
    */
    //swizzleBitmap(data, bytewidth, height);
    }

    cotton5415 responded:
    6 十一月, 2006 於 6:36 上午

    AbsoluteDeltaToDuration(a,b) returns nagative values in microseconds.

回覆給cotton5415 取消回覆