Skip to content

2D accelerator

Adan edited this page Aug 10, 2020 · 14 revisions

Overview

The MMSP2 chip within the GP2X has a simple 2D accelerator. It is designed for accelerating the drawing of a Windows CE UI, but the same features can be of use when writing games. It supports two kinds of acceleration: GDI ternary raster operations (blitting and filling); and rotation.

Both are run asynchronously, meaning you can get on with other work on the CPU at the same time. Helper functions are provided to wait for completion if desired (rgbRasterIsRunning(), rgbRasterWaitComplete(), rgbRotIsRunning(), rgbRotWaitComplete()).

Raster operations

The hardware provides a way of accelerating GDI ternary raster operations, which can be used to implement various functions (Orcus provides a few). The Microsoft GDI documentation provides full details of how these work, but at a high level, each operation manipulates pixels in the destination graphic by combining the equivalent pixel in the source, destination and pattern (each is optional and can be combined in different ways). In order to use custom raster operations, one has to use the rgbRasterOp() function (this is demonstrated in the 2D example), but this page will focus on the helper functions to perform common operations.

The 'pattern' is an 8x8 graphic which can be 1bpp, 8bpp (palette) or 16bpp (RGB565) and is accessible via the pointer pattern which lets one store up to 128 bytes of graphic data for this purpose.

Blit

Copy a rectangular region of graphical data onto another graphic, optionally omitting a specific colour which is defined as the transparent colour (by default this is 0xF81F, magenta in Orcus).

The following example configures a transparency colour of magenta in RGB565 format and copies an rectangle from (0, 0) of width and height (60, 60) within an image of the Sun onto the screen at (12, 34), blocking until the operation has completed:

  rgbSetTransparencyColour(0xF81F);
  rgbBlit(sun, &((Rect){0, 0, 60, 60}),
	  screen, 12, 34, true);
  rgbRasterRun();
  rgbRasterWaitComplete();

1bpp render

Render a 1bpp image to a destination of any colour format, specifying foreground and background colours in the destination format to be used when rendering. This is useful for fonts and possibly some icons.

As an example, the following code defines an 8x8 1bpp graphic in the shape of the letter 'A', then renders it to the screen in red with a transparent background at (8, 18).

  uint8_t letterA[8] = {0x18, 0x24, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42};
  Graphic* letterAG = &((Graphic){letterA, 8, 8, B1BPP});
  rgbBlit1bpp(letterAG, &((Rect){0, 0, 8, 8}), screen, 8, 188, true, RED, MAGENTA);
  rgbRasterRun();
  rgbRasterWaitComplete();

The 1bpp format is a bitset, where 1 represents the foreground colour, and 0 the background colour. To expand on the previous example, this is how the graphic data for 'A' is stored:

0x18 = 0b00011000 = ...XX...
0x24 = 0b00100100 = ..X..X..
0x42 = 0b01000010 = .X....X.
0x7E = 0b01111110 = .XXXXXX.
0x42 = 0b01000010 = .X....X.
0x42 = 0b01000010 = .X....X.
0x42 = 0b01000010 = .X....X.

Pattern fill

Fill an area with an 8x8 pattern, expanding 1bpp patterns using the given colours.

This example fills an area on the screen from (240, 0) which is (60, 60) pixels wide/high, with a 1px chequerboard pattern where alternate pixels are green and red:

  pattern[0] = 0xAA55AA55;
  pattern[1] = 0xAA55AA55;
  rgbPatternFill(screen, &((Rect){240, 0, 60, 60}), &((RasterPattern){GREEN, RED, B1BPP, 0}), false);
  rgbRasterRun();
  rgbRasterWaitComplete();

Solid fill

A variant on a pattern fill, where both the foreground and background colours of the pattern are set to a single colour resulting in a region filled with a solid colour.

This example fills an area on the screen from (180, 0) which is (60, 60) pixels wide/high with a solid green colour:

  rgbSolidFill(screen, &((Rect){180, 0, 60, 60}), GREEN);
  rgbRasterRun();
  rgbRasterWaitComplete();

Rotation

The rotation hardware is more limited than that for running raster operations. It can perform a simple graphic copy from one block of memory to another, while also rotating the source image by 0, 90, 180 or 270 degrees clockwise. It does not support transparency of any kind, so one would have to first rotate to an off-screen portion of memory, then use the raster blit if transparency is required.

The following example draws a picture of the sun to (120, 60) on the screen, rotated by 180 degrees.

  rgbRotBlit(sun, &((Rect){0, 0, 60, 60}),
	     screen, 120, 60, DEG180);
  rgbRotRun();
  rgbRotWaitComplete();

Accelerator in action

A photo of the 2D accelerator running

Clone this wiki locally