Warping Overview

This section explains the implementation of the Warping Library. It is used to adjust the image to be displayed so that it can be projected to a windscreen (which in the end shall result in a non-distorted image presented to the user).

Additionally, the Warping Library can apply graphic transformations like flipping and rotation to the image during the warping process.

Introduction

The Head-up display (HUD) projects information onto the windscreen glass. An image projected to the windscreen is distorted because the glass is not flat. For correcting this image distortion, warping process shall be used and the original image shall be prepared so that the driver can observe it on the windscreen linearly.

The basic principle of the Warping Library is to map a texture onto a grid, which's form compensates for the deformation of the windscreen when the information is projected on the HUD. The texture that is used is the readily rendered content for the HUD.

drawing-7-1676948061.png

CGI Studio Warping is intended to be used for correcting such image distortions. The following two components are involved in the process:

  • Warping Library: used for computing of the warping matrix
  • Candera: used to map a displays image (or part of it) as texture to a mesh created from the warping matrix information and displays the correspondingly distorted result.


CGI Studio Controller Integration Tool

The presented figure shows an overview of the information flow when using the CGI Studio Warping components.

drawing-7-1676948130.png

Three components can be identified, that together, implement the warping:

  • Application: Controls execution, prepares and passes information between the other two components
  • Warping Library: Computes the warping matrix and image bounds of the are to be warped
  • Candera: Applies the warping matrix and image bounds to the image rendered to a display, thus warping the desired portion of the overall display content.

System View

Below figure shows the location of the warping library in the system and which other components use it. Globally, the warping library consists of two parts, the warping application module and a warping platform module. The platform module is platform dependent - a version for Windows host platform and a version for target hardware are available (although several platforms share the same implementation). Responsibility for each part is described in the system view.

drawing-7-1676948161.png

Warping Functionality

The Warping Library supports the following functionality:

  • Warp matrix computation
  • Warp matrix adjustment
  • Reference Point Shift Vector encoding and retrieval
  • Warp image bounds computation

Warp Matrix Computation

Input:
Output:
  • Warp Matrix
Algorithm:
  • Decode and cache the reference point shift vectors.
  • Computation of warp matrix from reference points and corresponding shift vectors. The reference points are distributed over the whole bitmap area according to the specifications in the parameter list.
  • Rotation of warp matrix. The rotation of the warped reference points take place aroung the center point of the warped bitmap. (please refer to Rotation and Scale)
  • Scaling of warp matrix to illuminated area, if outside of illuminated area. (please refer to Rotation and Scale)
  • Normalize of warp matrix. Candera uses normalized coordinates in range [0..1] for rendering, therefore the warp matrix data has to be normalized in this range.
Interface:

CalculateWarpMatrix(const stc_warp_configuration_parameter_t* const pstcWarpConfigParams, const stc_warp_parameter_set_t* const pstcWarpRefPoints, stc_warp_matrix_t* pstcWarpMatrix)


Warp Matrix Adjustment

Input:
  • Configuration information.
  • Adjustment configuration (please refer to Adjustments).
Output:
  • Warp Matrix
Algorithm:
  • Adjustment of reference point shift vectors according to the specified adjustment configuration structure using the according mathematical formulas.
  • Computation of warp matrix from reference points and corresponding shift vectors.
  • Rotation of warp matrix.
  • Scaling of warp matrix to illuminated area, if outside of illuminated area.
  • Normalize of warp matrix.
Interface:

AdjustWarpMatrix(const stc_warp_configuration_parameter_t* const pstcWarpConfigParams, const stc_warp_adjust_parameter_t* const pstcWarpAdjustParams, en_warp_bool_t* pbRefPointsChanged, stc_warp_matrix_t* pstcWarpMatrix)


Reference Points Encoding and Retrieval

Input:
  • Internally cached configuration
  • Internally cached shift vectors
Output:
  • Encoded bitmap image shift vectors
Algorithm:
  • Encode shift vectors.
  • Write shift vectors to application supplied memory location.

The current active reference point shift vector set is retrieved from the warping library. Shift vectors are encoded according to the provided configuration.

Interface:

GetRefPoints(stc_warp_parameter_set_t* pstcWarpRefPoints)


Warp Image Bounds Computation

Input:
  • Configuration information.
Output:
  • Bitmap image area bounds in normalized coordinates
Algorithm:
  • Calculate area bounds based on the provided configuration information:
    • x = (bitmapAreaShiftX - bitmapAreaX/2) / displaySizeX
    • y = (bitmapAreaShiftY - bitmapAreaY/2) / displaySizeY
    • width = bitmapAreaX / displaySizeX
    • height = bitmapAreaY / displaySizeY

The image area bounds are normalized as required by Candera, as it uses normalized coordinates in range [0..1] for rendering.

Interface:

ComputeWarpImageBoundsFromConfig(stc_warp_configuration_parameter_t* config, WRP_SFLOAT* x, WRP_SFLOAT* y, WRP_SFLOAT* width, WRP_SFLOAT* height)



Using Warping with Candera

Following are the display properties that required adjustment to use warping with Candera:

  • Enable warping - this should be done before the native handle is available
  • Set warp matrix
  • Set warp image bounds (optional)
  • Apply display settings

Candera::Display class uses a transaction based execution model for setting properties. Several changes can be queued. Changes have to be applied explicitly via a call to Display::ApplyChanges(). Warping matrix data from the warping library can be used directly in Candera.

Execution Overview

Warping is executed in the following steps:

  • Warping mesh creation
  • Rendering of display image to texture
  • Texture mapping of rendered image aperture specified by warp images bounds to the warping mesh

Display content is rendered to a texture. This texture is clipped according to the warp image bounds and the resulting texture is mapped to the warp mesh and rendered in 3D using OpenGL and a very simple shader program.

Mesh and Texture Creation

Upon rendering of a displays content, Candera checks, if:

  • Warping has been en- or disabled
  • Warp matrix has changed
  • Image bounds have changed

If any of these conditions holds, the currently used warping mesh is unloaded. A new warping mesh is computed from the warp matrix as well as the image bounds and uploaded. Vertices in the warp mesh directly map to the corresponding values in the warp matrix. Texture coordinates for vertices are computed from warp mesh vertices as well as warp image bounds. The texture is mapped to the warping mesh and distorted corresponding to the position of the of the warping mesh vertices.


Configuration of warping parameters

The configuration information passed to the warping library is used to check constraints and as basis for computations.

Overall configuration parameter structure

The following table details the overall configuration parameter structure and their limits.

Name Range Description Example Value
NumBitsPerParam 1..16 Number of bits used for each parameter (bit length of each parameter, contains pixel fractions) 12
PixResolution 0: 1/16 px
1: 1/8 px
2: 1/4 px
3: 1/2 px
4: 1 px
5: 2 px
6: 4 px
7: 8 px
Resolution of warping parameters. 0 (1/16 px)
DisplaySizeX 0..655535 Display size in horizontal direction (in pixel). 480
DisplaySizeY 0..655535 Display size in vertical direction (in pixel). 240
BitmapAreaX 0..655535

Number of Bitmap-pixels in horizontal direction. Reference points are equally distributed over this range in x-direction.

Condition:
BitmapAreaX ≤ DisplaySizeX

480
BitmapAreaY 0..655535

Number of Bitmap-pixels in vertical direction. Reference points are equally distributed over this range in y-direction.

Condition:
BitmapAreaY ≤ DisplaySizeY

240
BitmapAreaShiftX 0..655535

Shift of the bitmap area center point in horizontal direction.

Condition:
(BitmapAreaX/2+BitmapAreaShiftX≤DisplaySizeX) AND (BitmapAreaX/2– BitmapAreaShiftX ≥0)

240
BitmapAreaShiftY 0..655535

Shift of the bitmap area center point in vertical direction.

Condition:
(BitmapAreaY/2+BitmapAreaShiftY≤DisplaySizeY) AND (BitmapAreaY/2– BitmapAreaShiftY ≥0)

120
IlluminatedDisplayAreaX 0..655535

Number of illuminated pixels in horizontal direction

Condition:
IlluminatedDisplayAreaX ≤DisplaySizeY

480
IlluminatedDisplayAreaY 0..655535

Number of illuminated pixels in vertical direction

Condition:
IlluminatedDisplayAreaY ≤DisplaySizeY

220
IlluminatedDisplayAreaShiftX 0..655535

Shift of the illuminated display area center point in horizontal direction.

Condition:
(IllDisplayAreaX/2+IllDisplayAreaShiftX≤DisplaySizeX) AND (IllDisplayAreaX/2– IllDisplayAreaShiftX ≥0)

480
IlluminatedDisplayAreaShiftY 0..655535

Shift of the illuminated display area center point in vertical direction.

Condition:
(IllDisplayAreaY/2+IllDisplayAreaShiftY≤DisplaySizeY) AND (IllDisplayAreaY/2– IllDisplayAreaShiftY ≥0)

220
WarpingAreaX 0..655535

Number of pixels used for warping in horizontal direction.

Condition:
WarpingAreaX≤IlluminatedDisplayAreaX


This parameter is present for historical reasons and is not used during computation/adjustment. Its validity is still checked, though.

470
WarpingAreaY 0..655535

Number of pixels used for warping in vertical direction.

Condition:
WarpingAreaY≤IlluminatedDisplayAreaY

This parameter is present for historical reasons and is not used during computation/adjustment. Its validity is still checked, though.

120
WarpedAreaShiftX 0..655535

Shift of the warped area center point in horizontal direction.


This parameter is present for historical reasons and is not used during computation/adjustment. Its validity is still checked, though.

220
WarpedAreaShiftY 0..655535

Shift of the warped area center point in vertical direction.

This parameter is present for historical reasons and is not used during computation/adjustment. Its validity is still checked, though.

110
RotationValue -18000 .. +18000 Rotation value in grad * 100 -150 // rotate 1.5°
ParamSet Data
Set of reference point shift vectors row-major ordered(left to right, top to bottom).
Each reference point in x/y direction is represented as a signed integer value in range –32,768 .. 32,767 (2 bytes).
(X0, Y0)
(X0, Y1)

(XM, YN)

M: #RefPointsX
N: #RefPointsY
ParamSetLength 0..655535 Length of parameter set in bytes calculated using the following formula:
2 * NumRefPointsX * NumRefPointsY * NumBitsPerParam / 8
825 // 2*25*11*12/8
RotationLimit 0..180 Maximal rotation angle in grad (+/- value) 5 // +/- 5°
TrapezoidLimitX 0..655535 Maximum value for trapezoid transformation in horizontal direction (+/- value) 50
TrapezoidLimitY 0..655535 Maximum value for trapezoid transformation in vertical direction (+/- value) 50
ParallelogramLimitX 0..655535 Maximum value for parallelogram transformation in horizontal direction (+/- value) 50
ParallelogramLimitY 0..655535 Maximum value for parallelogram transformation in vertical direction (+/- value) 50
PinbalanceLimitX 0..655535 Maximum value for pin balance transformation in horizontal direction (+/- value) 50
PinbalanceLimitY 0..655535 Maximum value for pin balance transformation in vetical direction (+/- value) 50
PincushionLimitX 0..655535 Maximum value for pincushion transformation in horizontal direction (+/- value) 50
PincushionLimitY 0..655535 Maximum value for pincushion transformation in vetical direction (+/- value) 50
WidthLimit 0..655535 Maximum value for width transformation in horizontal direction (+/- value) 50
HeightLimit 0..655535 Maximum value for height transformation in vetical direction (+/- value) 50
ScaleMode 0 or 1

0 - scale factor is 1. Scaling might occur if image does not fit inside illuminated area

1 - scale factor is calculated based on RotationLimit value, such that, when rotated at maximum, the image will fit inside illuminated area

0

Please refer to the following chapters for details on how the parameters influence the result of the warped image.



Warping Areas

The display area comprises the whole image including the grey border, as depicted in the figure below.

The bitmap image area is the area within the grey border. This is the area of interest and which should be warped. The reference points are evenly distributed over the bitmap image area.

The illuminated display area is the part of the display, which is backlit and projected to the windshield. This is the area where the warped image will be rendered into. If the bitmap image area is larger than the specified illuminated display area, then the warp image will be scaled to fit into the illuminated area boundaries.

drawing-7-1676953032.png

The Warping Library needs the following parameters to be configured which are related to the warping areas:

  • Display Size X/Y: area of the display size
  • Bitmap Area X/Y: area for the warping screen
  • Bitmap Shift Area X/Y: shift values of bitmap area center point
  • Illuminated Area X/Y: area of the illuminated area
  • Illuminated Shift Area X/Y: shift value of illuminated area center point
  • Warping Area (parameter is no longer used in the calculation of the warp image, but the values are checked for boundary correctness - use same values as for illumination area).
  • Warping Shift Area (parameter is no longer used in the calculation of the warp image, but the values are checked for boundary correctness - use same values as for illumination shift area).

The Bitmap Shift Area describes the connection vector between the origin of the bitmap coordinate system (0,0) and the center point of the bitmap image - the Bitmap Area Center Point. This center point represents the center point of the image area.

Example

Warp image is influenced by the size of bitmap area and illuminated area.

Reference points are distributed over display area
Display Area: 480x240
BitmapArea: 480x240 | BitmapShiftArea: 240x120
IlluminatedArea: 480x240 | IlluminatedShiftArea: 240x120

drawing-7-1676953116.png


Content shrinks to fit inside illuminated area
Display Area: 480x240
BitmapArea: 480x240 | BitmapShiftArea: 240x120
IlluminatedArea: 409x190 | IlluminatedShiftArea: 240x120

drawing-7-1676953143.png


Bitmap area changes, content shrinks even more to fit inside illuminated area
Display Area: 480x240
BitmapArea: 409x190 | BitmapShiftArea: 240x120
IlluminatedArea: 480x240 | IlluminatedShiftArea: 240x120

drawing-7-1676953163.png


Position of the warp image inside the illuminated area can by influenced by the corresponding BitmapShiftArea parameters. Similarly, the position of the illuminated area is given by the IlluminatedShiftArea. For better visualizing this, no pre-distortion was applied.

Top left aligned
Display Area: 480x240
BitmapArea: 409x190 | BitmapShiftArea: 205x95
IlluminatedArea: 480x240 | IlluminatedShiftArea: 240x120

drawing-7-1676953201.png


Center aligned
Display Area: 480x240
BitmapArea: 409x190 | BitmapShiftArea: 240x120
IlluminatedArea: 480x240 | IlluminatedShiftArea: 240x120

drawing-7-1676953234.png


Bottom right aligned
Display Area: 480x240
BitmapArea: 409x190 | BitmapShiftArea: 276x145
IlluminatedArea: 480x240 | IlluminatedShiftArea: 240x120

drawing-7-1676953260.png


For the presented use cases, the warp image bounds were not specified. (see Warp Image Bounds for more details)


Pixel Resolution and Number of Bits per Parameter

Pixel Resolution

The pixel resolution determines the warping accuracy. The final displacement of a reference point is the product of the warping parameter by parameter resolution. A warping parameter is therefore given by the desired displacement divided by resolution.

The resolution values supported by the warping library are: 0: 1/16 px, 1: 1/8 px, 2: 1/4 px, 3: 1/2 px, 4: 1 px, 5: 2 px, 6: 4 px, 7: 8 px.

Example

PixResolution: 0
Factor for multiplying: 0.0625f

drawing-7-1676953501.png


PixResolution: 1
Factor for multiplying: 0.125f

drawing-7-1676953527.png


PixResolution: 2
Factor for multiplying: 0.25f

drawing-7-1676953546.png


PixResolution: 3
Factor for multiplying: 0.5f

drawing-7-1676953579.png


PixResolution: 4
Factor for multiplying: 1.0f

drawing-7-1676953593.png


PixResolution > 4
WarpMatrix is no longer computed since delta calculation leads to "out of trapezoid limit" error

Number of Bits per Parameter

The configuration parameter "NumOfBitsPerParam" gives the allowed range for the warping parameter data. Therefore, each parameter is represented as a signed integer value of the given bit width.

If n is the number of bits, then the allowed range is: -(2n-1) .. + (2n-1- 1).

Maximum possible value for "NumOfBitsPerParam" is 16. Considering this, the maximum allowed range for the warping parameter data is: −32 768 .. 32 767.

The length of the parameter data is given by the following formula: 2 * NumOfRefPointsX * NumOfRefPointsY * NumOfBitsPerParam / 8.

Example
  • if "NumOfBitsPerParam" is 8, the warping parameter corresponding to point XnYn is represented as: 0xA0 0xA0
  • if "NumOfBitsPerParam" is 12, the warping parameter corresponding to point XnYn is represented as: 0x0A 0x00 0xA0

NumOfBitsPerParam: 8

drawing-7-1676953439.png

NumOfBitsPerParam: 12

drawing-7-1676953455.png

 

Reference Points and the Warp Matrix

The warping parameters are based on reference points. These points are mapped by a 2D array containing coordinates inside the bitmap area to be warped.

For each reference point, a shift vector is stored by the application. Every shift vector determines the amount of distortion to be applied to the corresponding point in x- and y-direction. The warping parameter correspond to the shift vectors (in pixels) of warping interpolation point in warped images, in comparison to reference points in non-warped images (divided by the specified pixel resolution). To save memory space and computing time, the absolute coordinates are not saved as warping parameters, but rather only the distance from the reference points (without rotation and shifting).

The figure below shows a reference point grid with corresponding shift vectors.

drawing-7-1676953789.png

CGI Studio Warping Library used row-major data ordering for area shift vector sets.

The warp matrix is a two-dimensional matrix computed by the warping library. Each point corresponds to a bitmap image reference point that has been shifted. The value of each point is the vector-addition of the reference point and the corresponding shift vector with regards to pixel resolution. All values of the warp matrix are normalized to the range [0..1] at the end of warp matrix computation or adjustment in order to be used by Candera.

The Warping Library does not provide an interface that supports the usage of "final shifted" points instead of the shift vectors. In such case, the library cannot be used. These "final shifted" points can serve as entry point in calculating the Candera::WarpMatrix data.

Example

The number of reference points influence the output of the warp matrix. The points should be chosen, proportionally, with regards to the size of the bitmap area. The larger the value, the more accurate and smooth the result of the warp image.

NumOfRefPointsX: 4 | NumOfRefPointsY: 2

drawing-7-1676953828.png


NumOfRefPointsX: 2 | NumOfRefPointsY: 4

drawing-7-1676953856.png


NumOfRefPointsX: 4 | NumOfRefPointsY: 4

drawing-7-1676953885.png


NumOfRefPointsX: 11 | NumOfRefPointsY: 5

drawing-7-1676953906.png

Adjustments

An adjustment is specified by a mode, a direction and a delta. For each reference point and corresponding shift vector, the adjustment is computed and applied. The resulting shift vector is again cached in the warping library. This way of implementation allows incremental adjustments.

Mode defines the way of the distortion. Following modes are available:

  • Parallelogram
  • Trapezoid
  • Pin balance
  • Pincushion
  • Shift
  • Size
  • Rotation (around bitmap image center point)

Direction specifies the direction in which the distortion is applied. Following directions are available:

  • Up
  • Down
  • Left
  • Right

Delta specifies the amount of distortion that is applied. Delta is an unsigned integer value in range 0..255 (1 byte). The delta is added to the existing offset of the corresponding reference points.

Predefined Adjustments

Based on mode and direction, the following transformations are possible:

Mode
Direction
Trapezoid Parallelogram Pincushion Pin balance
Up
drawing-7-1676954059.png
drawing-7-1676954316.png
drawing-7-1676954403.png
drawing-7-1676954492.png
Down
drawing-7-1676954095.png
drawing-7-1676954336.png
drawing-7-1676954419.png
drawing-7-1676954511.png
Left
drawing-7-1676954115.png
drawing-7-1676954356.png
drawing-7-1676954442.png
drawing-7-1676954527.png
Right
drawing-7-1676954131.png
drawing-7-1676954376.png
drawing-7-1676954457.png
drawing-7-1676954547.png


Mode
Direction
Size Rotation Shift
Up
drawing-7-1676954601.png

drawing-7-1676955044.png
Down
drawing-7-1676954905.png

drawing-7-1676955092.png
Left
drawing-7-1676954925.png
drawing-7-1676954990.png
drawing-7-1676955117.png
Right
drawing-7-1676954948.png
drawing-7-1676955009.png
drawing-7-1676955136.png

Formulas for adjustments

The following formulas describe the mathematically necessary adjustments of the reference points. If the requested adjustment exceeds the limit, no calculation shall be done and the previous status will be kept.

Trapezoid mode
drawing-7-1676955237.png
Parallelogram mode
drawing-7-1676955457.png
Pinbalance mode
drawing-7-1676955477.png
Pincushion mode
drawing-7-1676955492.png
Size mode
drawing-7-1676955650.png
Rotation mode
drawing-7-1676955526.png
Shift mode
drawing-7-1676955542.png

NumOfRefPointsX - number of reference points in horizontal direction
NumOfRefPointsY - number of reference points in vertical direction
x[i][j] - x-coordinate of reference point, a 2-dimensional array of floating point variables
y[i][j] - y-coordinate of reference point, a 2-dimensional array of floating point variables


Rotation and Scale

Rotation

The rotation takes place around the warped center point of the bitmap area.

If an uneven number of reference points in x/y direction is specified, the warped center point coincides with the middle reference grid point and the coordinates of the rotation axis are present. If an even number of reference grid points is use, the coordinates of the warped center point are calculated.

An initial RotationValue and the RotationLimit are specified through the configuration parameter structure:

  • Initial Rotation value is represented in grad*100. This is the default rotation value that is applied to the warp image prior to rendering.
  • RotationLimit represents the maximum rotation angle in grad that the warped image will be rotated to. Both positive and negative values are accepted.

Warp image rotation at run-time is achieved through the adjustments supported by the Warping Library. Subsequent calls of warp matrix adjustments result in incremental rotation of the warp image with an incremental step equal to the specified delta value.

If the initial RotationValue exceeds the specified RotationLimit a WarpResultErrorConfigInvalidValue will be thrown and the calculation of the warp matrix will be aborted.
Scaling of the warp image occurs when the RotationLimit value is chosen such that at maximum rotation point, the image will extend beyond the illuminated area. More details related to image scaling is presented in the next section.

Example
RotationValue: 500 | Rotate 5° to right
drawing-7-1676962027.png
RotationValue: -1000 | Rotate 10° to left
drawing-7-1676962039.png
RotationValue: 3000 | Rotate 30° to right
drawing-7-1676962049.png
RotationValue: -4500 | Rotate 45° to left
drawing-7-1676962063.png

Scaling

The warping library performs automatic rescaling of the resulting warping matrix whenever it overlaps or exceeds the boundaries of the illuminated area. It is possible to identify two cases in which rescaling will be done:

  • If the configured illuminated area is smaller than the bitmap area, the resulting warp matrix will be rescaled to the specified illuminated area.
  • If the RotationLimit value is chosen such that at maxim rotation point, the warp image will extend beyond illuminated area boundaries.


The ScaleMode parameter influences the behavior of scaling by modifying the internal scale factor:

  • 0 - scale factor is 1. Scaling occurs only if the image does not fit inside illuminated area. Rotating the warp image at run-time will rescale the resulted rotated image if it falls outside illuminated area boundaries.
  • 1 - scale factor is calculated based on RotationLimit value. The warp image will be scaled down to the size that fits inside the illuminated area when a rotation equal to RotationLimit is applied.
Example
No Scaling occurs
BitmapArea: 408x190 | Illuminated Area: 480x190

drawing-7-1676961634.png
Scaling occurs because bitmap area exceeds illuminated area
BitmapArea: 408x190 | Illuminated Area: 375x190
drawing-7-1676961611.png
No Scaling occurs since warp image does not exceed illuminated area
BitmapArea: 408x190 | Illuminated Area: 480x190
RotationValue: 0° | RotationLimit: 45°
ScaleMode: 0
drawing-7-1676961696.png
Scaling occurs because of specified RotationLimit and ScaleMode
BitmapArea: 408x190 | Illuminated Area: 480x190
RotationValue: 0° | RotationLimit: 45°
ScaleMode: 1
drawing-7-1676961721.png
Scaling down during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 0
drawing-7-1676961751.png
Scaling down during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 0
drawing-7-1676961773.png
Scaling down during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 0
drawing-7-1676961780.png
Scaling down during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 0
drawing-7-1676961789.png
No scaling during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 1
drawing-7-1676961799.png
No scaling during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 1
drawing-7-1676961810.png
No scaling during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 1
drawing-7-1676961820.png
No scaling during incremental rotation
BitmapArea: 408x190 | Illuminated Area: 480x190
ScaleMode: 1
drawing-7-1676961828.png

Image Flipping

Flipping transforms the content prior to warping the image on screen. Flipping is supported only when warping is enabled. The following orientations are supported:

  • Candera::DisplayOrientation::Unchanged
  • Candera::DisplayOrientation::HorizontallyFlipped
  • Candera::DisplayOrientation::VerticallyFlipped
  • Candera::DisplayOrientation::VerticallyAndHorizontallyFlipped

Changing the image orientation is achieved through the public interface of Candera::Display class using Candera::Display::SetWarpOrientation, like in the following snippet.

    // flip the image vertically and horizontally
    display->SetWarpOrientation(Candera::DisplayOrientation::VerticallyAndHorizontallyFlipped);
Example
Unchanged
drawing-7-1676962188.png
HorizontallyFlipped
drawing-7-1676962198.png
VerticallyFlipped
drawing-7-1676962217.png
VerticallyAndHorizontallyFlipped
drawing-7-1676962226.png

 

Warp Image Bounds

Warp image bounds comprise upper left corner point of the bitmap image area, its width, and height (normalized to the range [0..1]).

They are used to specify to Candera which part of the rendered display image shall be mapped to the warping mesh computed from the warp matrix. If not specified, then the complete display image will be mapped.

The following code snippet shows how to retrieve the warp image bounds from the Warping library. These can be further passed to Candera through the public interface of Candera::Display class using Candera::Display::SetWarpImageBounds.

    WRP_SFLOAT textureOriginX; 
    WRP_SFLOAT textureOriginY;
    WRP_SFLOAT textureWidth;
    WRP_SFLOAT textureHeight;
    
    // retrieve warpTextureBounds
    ComputeWarpImageBoundsFromConfig(&stcWarpConfigParams, &textureOriginX, &textureOriginY, &textureWidth, &textureHeight);
    Candera::Rectangle warpTextureBounds(textureOriginX, textureOriginY, textureWidth, textureHeight);
      
    // set the bounds of the warping texture  
    display->SetWarpImageBounds(warpTextureBounds);
Example
Warping is disabled
Display Area: 480x240
BitmapArea: 408x190
drawing-7-1676962315.png
Warping is enabled, image bounds are not specified
Display Area: 480x240
BitmapArea: 408x190 | Illuminated Area: 480x240
drawing-7-1676962331.png
Warping is enabled, image bounds are specified
Display Area: 480x240
BitmapArea: 408x190 | Illuminated Area: 480x240
drawing-7-1676962355.png

Appendix A: Sample code

Please refer to the following code snippets for information on how to the Warping Library and Candera are used in order to calculate the warped output that will be rendered on display.

Create Warp Matrix

    en_warp_result_t enResult = WarpResultSuccess;          // Enumeration for possible return values of warping library functions.
    stc_warp_configuration_parameter_t stcWarpConfigParams; // Warping configuration parameters and limit parameters.
    stc_warp_parameter_set_t stcWarpParamSet;               // Structure of the encoded input parameter set for the reference points.
    stc_warp_matrix_t stcWarpMatrix;                        // Structure for the calculated matrix vertex points.
    
    ... // Specify the configuration parameters and the input parameter set according the project needs
    
    // generate the warp matrix based on provided input configuration data
    enResult = CalculateWarpMatrix(&stcWarpConfigParams, &stcWarpParamSet, &stcWarpMatrix);

    // check return error of previous call
    if (enResult == WarpResultSuccess) {
        FEATSTD_LOG_DEBUG("Warp matrix succsessfully created.\n");
    } else {
        FEATSTD_LOG_DEBUG("Failed to create warp matrix.\n");
    }

Warp Matrix Adjustments

    en_warp_result_t enResult = WarpResultSuccess;          // Enumeration for possible return values of warping library functions.
    stc_warp_configuration_parameter_t stcWarpConfigParams; // Warping configuration parameters and limit parameters.
    stc_warp_adjust_parameter_t stcWarpAdjustParams;        // Structure with all parameters for delta calculation.
    stc_warp_matrix_t stcWarpMatrix;                        // Structure for the calculated matrix vertex points.
    en_warp_bool_t bSuccess;
    
    ... // Specify the configuration parameters
    
    // Specify parameters for delta calculation (example)
    stcWarpAdjustParams.WarpAdjustMode = WarpAdjustModeTrapezoid;
    stcWarpAdjustParams.WarpAdjustDirection = WarpAdjustDirectionDown;
    stcWarpAdjustParams.WarpDelta = 100;
    
    enResult = AdjustWarpMatrix(&stcWarpConfigParams, &stcWarpAdjustParams, &bSuccess, &stcWarpMatrix);

    if (enResult == WarpResultSuccess) {
        FEATSTD_LOG_DEBUG("Adjusted warp matrix.\n");
    } else {
        FEATSTD_LOG_DEBUG("Failed to adjust warp matrix.\n");
    }

Create the Candera WarpMatrix from the previously calculated warp matrix


      // Create warp matrix. This is a proof of the disposer concept.
      // The matrix data doesn't need to be copied, since it is static and can
      // be simply set into the warp matrix without a disposer.
      Candera::Float* matrixData = CANDERA_NEW_ARRAY(Candera::Float, 2 * stcWarpMatrix.usNumRefPointsX * stcWarpMatrix.usNumRefPointsY);
      if (matrixData == 0) {
        FEATSTD_LOG_ERROR("failed to allocate matrix data");
        return;
      }
      Candera::MemoryPlatform::Copy(matrixData, FeatStd::Internal::PointerToPointer<void*>(stcWarpMatrix.pVertex), 2 * stcWarpMatrix.usNumRefPointsX * stcWarpMatrix.usNumRefPointsY * sizeof(Candera::Float));
      typedef Candera::MemoryManagement::AdaptedArrayDisposer<Candera::WarpMatrix::ConstData, const Candera::Float*> MatrixDataDisposer;
      Candera::WarpMatrix warpMatrix(stcWarpMatrix.usNumRefPointsX, stcWarpMatrix.usNumRefPointsY, matrixData, &MatrixDataDisposer::Dispose);

Calculate Warp Texture Bounds

      WRP_SFLOAT textureOriginX; 
      WRP_SFLOAT textureOriginY;
      WRP_SFLOAT textureWidth;
      WRP_SFLOAT textureHeight;
      
      ComputeWarpImageBoundsFromConfig(&stcWarpConfigParams, &textureOriginX, &textureOriginY, &textureWidth, &textureHeight);
      Candera::Rectangle warpTextureBounds(textureOriginX, textureOriginY, textureWidth, textureHeight);

Render Warped Image to Display

      // define display parameters
      Candera::Display::CommonSettings params;
      Candera::MemoryPlatform::Set(&params, 0, sizeof(params));

      params.width =          800;
      params.hps =            832;
      params.hpe =            976;
      params.hpt =            1008;
      
      params.height =         600; 
      params.vps =            612; 
      params.vpe =            618; 
      params.vpt =            631;
        
      params.refreshRate =    60;
      params.colorBits =      32;
      
      // create display
      Candera::Display *display = Candera::DevicePackageInterface::CreateDisplay(0);
      if (display == 0) {
          FEATSTD_LOG_ERROR("Failed to create display.");
          return false;
      }
      
      //enable warping
      display->SetWarpingEnabled(true);
      
      // pass previously created Candera warpMatrix to display
      display->SetWarpMatrix(warpMatrix);          
      
      // optionally, set the warp texture bounds
      display->SetWarpImageBounds(warpTextureBounds);
      
      // ApplyChanges() has to be called for the changes to be taken into account
      display->ApplyChanges(); 
      
      //upload display
      if (!display->Upload(params)) {
          FEATSTD_LOG_ERROR("Failed to upload display.");
          return false;
      }

Warping should be enabled before the NativeHandle is attached to the display (attached either by AttachNativeHandle or created at display upload).

Create a Default WarpMatrix Data

      // retrieve display
      Candera::Display *display = Candera::DevicePackageInterface::GetDisplay(0);
      
      if (display == 0) {
        FEATSTD_LOG_ERROR("Failed to retrieve display.");
        return false;
      }      
      
      // default warpMatrix data
      static const Candera::Float data[] = {
                0.0F, 0.0F,
                1.0F, 0.0F,
                0.0F, 1.0F,
                1.0F, 1.0F,
            };
      
      Candera::WarpMatrix warpMatrix(2, 2, data);
      display->SetWarpMatrix(warpMatrix);
      
      Candera::Rectangle defaultImageBounds(0.F, 0.F, 1.F, 1.F);
      display->SetWarpImageBounds(defaultImageBounds);