docs
Loading...
Searching...
No Matches
CAPI_Surface.h

Overview

User-defined pixel buffer surface.

#include <Ultralight/CAPI/CAPI_Surface.h>

The library uses this to store pixel data when rendering Views on the CPU (see ulViewIsAccelerated()).

You can provide the library with your own Surface implementation to reduce the latency of displaying pixels in your application (Views will be drawn directly to a block of memory controlled by you).

When a View is rendered on the CPU, you can retrieve the backing Surface via ulViewGetSurface(). After each paint the Surface lists the rectangles the library changed (ulSurfaceGetDirtyRectCount(), ulSurfaceGetDirtyRect()); ulSurfaceGetDirtyBounds() is their union.

Precondition
This is automatically managed for you when using ulCreateApp(), if you want to override ULSurfaceDefinition, you'll need to use ulCreateRenderer() instead.

Default Implementation

A default Surface implementation, BitmapSurface, is automatically provided by the library when you call ulCreateRenderer() without defining a custom ULSurfaceDefinition.

You should cast the ULSurface to a ULBitmapSurface and call ulBitmapSurfaceGetBitmap() to access the underlying Bitmap.

Setting the Surface Implementation

To define your own implementation, you should implement the ULSurfaceDefinition callbacks, and then pass an instance of ULSurfaceDefinition containing your callbacks to ulPlatformSetSurfaceDefinition() before calling ulCreateRenderer().

Classes

struct  ULSurfaceDefinition
 User-defined surface interface. More...

Functions

unsigned int ulSurfaceGetWidth (ULSurface surface)
 Width (in pixels).
unsigned int ulSurfaceGetHeight (ULSurface surface)
 Height (in pixels).
unsigned int ulSurfaceGetRowBytes (ULSurface surface)
 Number of bytes between rows (usually width * 4).
size_t ulSurfaceGetSize (ULSurface surface)
 Size in bytes.
void * ulSurfaceLockPixels (ULSurface surface)
 Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.
void ulSurfaceUnlockPixels (ULSurface surface)
 Unlock the pixel buffer.
void ulSurfaceResize (ULSurface surface, unsigned int width, unsigned int height)
 Resize the pixel buffer to a certain width and height (both in pixels).
void ulSurfaceSetDirtyBounds (ULSurface surface, ULIntRect bounds)
 Set the dirty bounds to a certain value.
ULIntRect ulSurfaceGetDirtyBounds (ULSurface surface)
 Get the dirty bounds.
void ulSurfaceClearDirtyBounds (ULSurface surface)
 Clear the dirty bounds.
bool ulSurfaceScroll (ULSurface surface, ULIntRect rect, int dx, int dy)
 Shift a rectangle of pixels by a certain offset (see ULSurfaceDefinitionScrollCallback for the rules).
void ulSurfaceShiftPixels (void *pixels, unsigned int row_bytes, ULIntRect rect, int dx, int dy)
 Shift a rectangle of 32-bit pixels in place.
unsigned int ulSurfaceGetDirtyRectCount (ULSurface surface)
 Get the number of dirty rectangles (0 when nothing has been painted since the last clear).
ULIntRect ulSurfaceGetDirtyRect (ULSurface surface, unsigned int index)
 Get a dirty rectangle by index.
void * ulSurfaceGetUserData (ULSurface surface)
 Get the underlying user data pointer (this is only valid if you have set a custom surface implementation via ulPlatformSetSurfaceDefinition).
ULBitmap ulBitmapSurfaceGetBitmap (ULBitmapSurface surface)
 Get the underlying Bitmap from the default Surface.

Typedefs

typedef void *(*) ULSurfaceDefinitionCreateCallback(unsigned int width, unsigned int height)
 The callback invoked when a Surface is created.
typedef void(*) ULSurfaceDefinitionDestroyCallback(void *user_data)
 The callback invoked when a Surface is destroyed.
typedef unsigned int(*) ULSurfaceDefinitionGetWidthCallback(void *user_data)
 The callback invoked when a Surface's width (in pixels) is requested.
typedef unsigned int(*) ULSurfaceDefinitionGetHeightCallback(void *user_data)
 The callback invoked when a Surface's height (in pixels) is requested.
typedef unsigned int(*) ULSurfaceDefinitionGetRowBytesCallback(void *user_data)
 The callback invoked when a Surface's row bytes is requested.
typedef size_t(*) ULSurfaceDefinitionGetSizeCallback(void *user_data)
 The callback invoked when a Surface's size (in bytes) is requested.
typedef void *(*) ULSurfaceDefinitionLockPixelsCallback(void *user_data)
 The callback invoked when a Surface's pixel buffer is requested to be locked for reading/writing (should return a pointer to locked bytes).
typedef void(*) ULSurfaceDefinitionUnlockPixelsCallback(void *user_data)
 The callback invoked when a Surface's pixel buffer is requested to be unlocked after previously being locked.
typedef void(*) ULSurfaceDefinitionResizeCallback(void *user_data, unsigned int width, unsigned int height)
 The callback invoked when a Surface is requested to be resized to a certain width/height.
typedef bool(*) ULSurfaceDefinitionScrollCallback(void *user_data, ULIntRect rect, int dx, int dy)
 The callback invoked when a Surface is asked to shift a rectangle of pixels by an offset.

Function Documentation

◆ ulBitmapSurfaceGetBitmap()

ULBitmap ulBitmapSurfaceGetBitmap ( ULBitmapSurface surface)

Get the underlying Bitmap from the default Surface.

Note
Do not call ulDestroyBitmap() on the returned value, it is owned by the surface.

◆ ulSurfaceClearDirtyBounds()

void ulSurfaceClearDirtyBounds ( ULSurface surface)

Clear the dirty bounds.

You should call this after you're done displaying the Surface.

◆ ulSurfaceGetDirtyBounds()

ULIntRect ulSurfaceGetDirtyBounds ( ULSurface surface)

Get the dirty bounds.

This value can be used to determine which portion of the pixel buffer has been updated since the last call to ulSurfaceClearDirtyBounds().

The general algorithm to determine if a Surface needs display is:

// Surface pixels are dirty and needs display.
// Cast Surface to native Surface and use it here (pseudo code)
DisplaySurface(surface);
// Once you're done, clear the dirty bounds:
}
bool ulIntRectIsEmpty(ULIntRect rect)
Whether or not a ULIntRect is empty (all members equal to 0).
void ulSurfaceClearDirtyBounds(ULSurface surface)
Clear the dirty bounds.
ULIntRect ulSurfaceGetDirtyBounds(ULSurface surface)
Get the dirty bounds.

◆ ulSurfaceGetDirtyRect()

ULIntRect ulSurfaceGetDirtyRect ( ULSurface surface,
unsigned int index )

Get a dirty rectangle by index.

Each lies inside the dirty bounds; the dirty bounds are their union, so you can copy each one instead of the union to move fewer pixels.

Parameters
surfaceThe surface handle.
indexThe index of the rectangle (less than ulSurfaceGetDirtyRectCount()).
Returns
Returns the rectangle, or an empty rectangle for an index out of range.

◆ ulSurfaceGetDirtyRectCount()

unsigned int ulSurfaceGetDirtyRectCount ( ULSurface surface)

Get the number of dirty rectangles (0 when nothing has been painted since the last clear).

Parameters
surfaceThe surface handle.
Returns
Returns the number of dirty rectangles.

◆ ulSurfaceGetHeight()

unsigned int ulSurfaceGetHeight ( ULSurface surface)

Height (in pixels).

◆ ulSurfaceGetRowBytes()

unsigned int ulSurfaceGetRowBytes ( ULSurface surface)

Number of bytes between rows (usually width * 4).

◆ ulSurfaceGetSize()

size_t ulSurfaceGetSize ( ULSurface surface)

Size in bytes.

◆ ulSurfaceGetUserData()

void * ulSurfaceGetUserData ( ULSurface surface)

Get the underlying user data pointer (this is only valid if you have set a custom surface implementation via ulPlatformSetSurfaceDefinition).

This will return nullptr if this surface is the default ULBitmapSurface.

◆ ulSurfaceGetWidth()

unsigned int ulSurfaceGetWidth ( ULSurface surface)

Width (in pixels).

◆ ulSurfaceLockPixels()

void * ulSurfaceLockPixels ( ULSurface surface)

Lock the pixel buffer and get a pointer to the beginning of the data for reading/writing.

Native pixel format is premultiplied BGRA 32-bit (8 bits per channel).

◆ ulSurfaceResize()

void ulSurfaceResize ( ULSurface surface,
unsigned int width,
unsigned int height )

Resize the pixel buffer to a certain width and height (both in pixels).

This should never be called while pixels are locked.

◆ ulSurfaceScroll()

bool ulSurfaceScroll ( ULSurface surface,
ULIntRect rect,
int dx,
int dy )

Shift a rectangle of pixels by a certain offset (see ULSurfaceDefinitionScrollCallback for the rules).

Parameters
surfaceThe surface handle.
rectThe rectangle to shift (in pixels).
dxThe horizontal shift, in pixels (positive moves pixels to the right).
dyThe vertical shift, in pixels (positive moves pixels down).
Returns
Returns the scroll callback's answer, or false for the default surface.

◆ ulSurfaceSetDirtyBounds()

void ulSurfaceSetDirtyBounds ( ULSurface surface,
ULIntRect bounds )

Set the dirty bounds to a certain value.

This is called after the Renderer paints to an area of the pixel buffer. (The new value will be joined with the existing dirty_bounds())

◆ ulSurfaceShiftPixels()

void ulSurfaceShiftPixels ( void * pixels,
unsigned int row_bytes,
ULIntRect rect,
int dx,
int dy )

Shift a rectangle of 32-bit pixels in place.

Use this from your scroll callback to move the pixels of rect by dx and dy through the pointer you returned from the lock callback; overlapping rows and columns are handled for you.

Parameters
pixelsPointer to the first pixel of the buffer.
row_bytesNumber of bytes between rows (usually width * 4).
rectThe rectangle to shift (in pixels).
dxThe horizontal shift, in pixels (positive moves pixels to the right).
dyThe vertical shift, in pixels (positive moves pixels down).

◆ ulSurfaceUnlockPixels()

void ulSurfaceUnlockPixels ( ULSurface surface)

Unlock the pixel buffer.

Typedef Documentation

◆ ULSurfaceDefinitionCreateCallback

typedef void *(*) ULSurfaceDefinitionCreateCallback(unsigned int width, unsigned int height)

The callback invoked when a Surface is created.

Parameters
widthThe width in pixels.
heightThe height in pixels.
Returns
Return a pointer to user-defined data for the instance. This user data pointer will be passed to all other callbacks when operating on the instance.

◆ ULSurfaceDefinitionDestroyCallback

typedef void(*) ULSurfaceDefinitionDestroyCallback(void *user_data)

The callback invoked when a Surface is destroyed.

Parameters
user_dataUser data pointer uniquely identifying the surface.

◆ ULSurfaceDefinitionGetHeightCallback

typedef unsigned int(*) ULSurfaceDefinitionGetHeightCallback(void *user_data)

The callback invoked when a Surface's height (in pixels) is requested.

Parameters
user_dataUser data pointer uniquely identifying the surface.

◆ ULSurfaceDefinitionGetRowBytesCallback

typedef unsigned int(*) ULSurfaceDefinitionGetRowBytesCallback(void *user_data)

The callback invoked when a Surface's row bytes is requested.

Note
This value is also known as "stride". Usually width * 4.
Parameters
user_dataUser data pointer uniquely identifying the surface.

◆ ULSurfaceDefinitionGetSizeCallback

typedef size_t(*) ULSurfaceDefinitionGetSizeCallback(void *user_data)

The callback invoked when a Surface's size (in bytes) is requested.

Parameters
user_dataUser data pointer uniquely identifying the surface.

◆ ULSurfaceDefinitionGetWidthCallback

typedef unsigned int(*) ULSurfaceDefinitionGetWidthCallback(void *user_data)

The callback invoked when a Surface's width (in pixels) is requested.

Parameters
user_dataUser data pointer uniquely identifying the surface.

◆ ULSurfaceDefinitionLockPixelsCallback

typedef void *(*) ULSurfaceDefinitionLockPixelsCallback(void *user_data)

The callback invoked when a Surface's pixel buffer is requested to be locked for reading/writing (should return a pointer to locked bytes).

Parameters
user_dataUser data pointer uniquely identifying the surface.

◆ ULSurfaceDefinitionResizeCallback

typedef void(*) ULSurfaceDefinitionResizeCallback(void *user_data, unsigned int width, unsigned int height)

The callback invoked when a Surface is requested to be resized to a certain width/height.

Parameters
user_dataUser data pointer uniquely identifying the surface.
widthWidth in pixels.
heightHeight in pixels.

◆ ULSurfaceDefinitionScrollCallback

typedef bool(*) ULSurfaceDefinitionScrollCallback(void *user_data, ULIntRect rect, int dx, int dy)

The callback invoked when a Surface is asked to shift a rectangle of pixels by an offset.

The library calls this during ulRender() when a page scrolls, moving already painted pixels instead of repainting them. Afterward, the library repaints only the exposed strip.

The Surface pixel buffer is the source the library paints into. The destination is wherever you copy those pixels to display them (eg, a GPU texture or a window). This callback always shifts the source.

Most implementations do this with one call to ulSurfaceShiftPixels().

Parameters
user_dataUser data pointer uniquely identifying the surface.
rectThe rectangle to shift (in pixels). This always lies inside the surface, and the shift is smaller than the rectangle on each axis.
dxThe horizontal shift, in pixels (positive moves pixels to the right).
dyThe vertical shift, in pixels (positive moves pixels down).
Returns
Return false in most cases. This means the destination was not shifted. The library then adds rect to the dirty bounds so you copy the moved pixels from the source to the destination again. Return true only in the rare case where you shifted the destination by the same offset yourself (eg, you scrolled your window or copied within your GPU texture)– the library then reports only the newly exposed strip as dirty.
Note
This is called while pixels are locked (between the lock and unlock callbacks). Shift through the pointer you returned from the lock callback– do not lock the buffer again.
Note
Rows may be padded. Step rows by the row bytes, never by width * 4.

◆ ULSurfaceDefinitionUnlockPixelsCallback

typedef void(*) ULSurfaceDefinitionUnlockPixelsCallback(void *user_data)

The callback invoked when a Surface's pixel buffer is requested to be unlocked after previously being locked.

Parameters
user_dataUser data pointer uniquely identifying the surface.

Go to the source code of this file.