Display (bitmap overlay) - page 18 - General Discussion and Assistance - CHDK Forum

Display (bitmap overlay)

  • 242 Replies
  • 62684 Views
*

Offline kitor

  • *
  • 18
Re: Display (bitmap overlay)
« Reply #170 on: 11 / April / 2021, 10:15:18 »
Advertisements
I just imported M10 111a into Ghidra, so I'll have some details coming soon  ;)

Perhaps worth to mention that most or all framebuffers are fixed in PowerShot firmware, whereas (AFAIK) they are allocated at run-time in EOS firmware.

They are kind of allocated (addresses are passed up from gui_init_event), but they somehow seem to always end up in exactly the same address, on multiple firmware versions and even between cameras (R and RP)
« Last Edit: 11 / April / 2021, 10:17:40 by kitor »
Magic Lantern / EOS R / 200D

*

Offline reyalp

  • ******
  • 13109
Re: Display (bitmap overlay)
« Reply #171 on: 11 / April / 2021, 14:06:36 »
I just imported M10 111a into Ghidra, so I'll have some details coming soon  ;)
In case you haven't found them, there are some scripts to help with that https://chdk.fandom.com/wiki/Firmware_analysis_with_Ghidra
Don't forget what the H stands for.

*

Offline kitor

  • *
  • 18
Re: Display (bitmap overlay)
« Reply #172 on: 11 / April / 2021, 14:41:57 »
Thank you.
I have some problems with Ghidra auto-analysis, at some moment it stops progressing and then 30 minutes later it will crash (same issue I had with 200D ROM).

Before it crashed I managed to locate XimrExe (size of payload is 0x300, like on 200D), CreateMARV, and what I thought might be the code that is responsible for context setup. But with missing xrefs and crash later... I have to retry tomorrow, this time starting with those scripts. Saving a project may be a good idea too  :-X

One thing I noticed, MARV "flags" field is a little bit different than on later models, it seems to hold just color type ID and bytes per pixel. Not that surprising for early implementation.
Magic Lantern / EOS R / 200D

*

Offline srsa_4c

  • ******
  • 4393
Re: Display (bitmap overlay)
« Reply #173 on: 11 / April / 2021, 14:48:49 »
I just imported M10 111a into Ghidra, so I'll have some details coming soon
I forgot to mention that PowerShot-based firmwares provide very few Zico hints on the ARM side. A list of mzrm handlers is useful for identifying the ARM side functions. Attached is a list of the m10 handlers, starting with handler #0 (first valid handler is #2). Look up calls to mzrm_createmsg to use the IDs.


*

Offline reyalp

  • ******
  • 13109
Re: Display (bitmap overlay)
« Reply #174 on: 11 / April / 2021, 18:59:20 »
Look up calls to mzrm_createmsg to use the IDs.
Added scripts to use lists like this to comment / find calls in ghidra https://app.assembla.com/spaces/chdk/subversion/commits/5827

edit:
And one to name the calling function, if it only appears to create one type of mzrm message (which appears to be all of them on g7x and m10, at least) https://app.assembla.com/spaces/chdk/subversion/commits/5839
« Last Edit: 18 / April / 2021, 14:41:08 by reyalp »
Don't forget what the H stands for.

*

Offline kitor

  • *
  • 18
Re: Display (bitmap overlay)
« Reply #175 on: 12 / April / 2021, 14:34:52 »
Function at fc23d2b8 is responsible for redraw and for XimrContext structure population.
XimrContext is the structure passed as the first argument to most functions and then to XimrExe.

Disambiguation - we call VRAM structure "MARV" in Magic Lantern (little endian signature).
"Output Chunk" as well as "Ximr Context" are names directly taken from XCM on EOS R+. (XCMStatus EvShell command)

"Flags" field of MARV is a bit different to what I'm used to - possible values are  0x04000002, 0x05000004 and 0x07000002.
On the left "color type", on the right probably bytes per pixel.

Max 8 layers like on 200D. Layer definition inside Ximr Context has identical offsets to 200D.

Ximr functions are easy to find as they always take Ximr Context as first param.
All layer manipulation functions are easy distinguishable for that as 2nd param is checked to be below MAX_LAYER_COUNT (8 in case od Digic 6/7, 6 for Digic 8,X)

Bad news: The very first call is XimrInitializeContext, which means it is recreated on every redraw. This is different to 200D/M50 which does it once on init.
It is however a bit similar to R+ where this is handled by XCM on every redraw.

Now, some stubs. Declarations fit those from 200D.
Names of those stubs are made up by their function, no strings exists for those in EOS roms too.
I left numbered params where I'm not sure of their meaning, but they are saved into XimrContext structure.
Code: [Select]
fc3ed850 XimrInitializeContext(pXC)

fc3edac0 XimrSetLayerVisibility(*pXC, layer_id, state)
fc3edcae XimrSetLayerColorParams(*pXC, layer, *pMARV, color_id, p5)
fc3edae0 XimrSetLayerMARV(*pXC, layer_id, *pMARV, p4)
fc3edb26 XimrSetLayerDimensions(*pXC, layer, src_x, src_y, src_w, src_h, dst_x, dst_y)

fc3edc30 XimrSetLayer_related_fc3edc30(pXC, layer_id, p3, p4, p5)
fc3edc68 XimrSetLayer_related_fc3edc68(pXC, layer_id, p3, p4, p5)


fc3ed9ec XimrSetOutputChunkMARV(*pXC, *pMARV)
fc3edaa2 XimrSetOputChunkResolution(*pXC, w, h)

Decomp of those functions is weird to understand, as it has the same caveat as 200D, R and R6:
Code: [Select]
pLayer = (XimrLayerData_withOffset *)((int)pContext + layerId * 0x3c);There's some compiler optimization going on there, you need to offset actual context inside structure definition.

Undefined fields were not referenced (at least on 200D). Fields with _<offset> name - referenced, but unknown meaning, may have wrong data size.
Code: [Select]
struct XimrLayerData_withOffset {
    //add fake paddng
    uint8_t _0x48;
    uint8_t _0x49;
    undefined field_0x4a;
    uint8_t _0x4b;
    uint8_t _0x4c;
    uint8_t _0x4d;
    undefined field_0x4e;
    undefined field_0x4f;
    undefined field_0x50;
    undefined field_0x51;
    uint8_t _0x52;
    uint8_t _0x53;
    uint8_t _0x54;
    uint8_t color_type;
    uint8_t visibility;
    uint8_t _0x57;
    undefined field_0x58;
    undefined field_0x59;
    uint16_t src_y;
    uint16_t src_x;
    uint16_t src_h;
    uint16_t src_w;
    uint16_t dst_y;
    uint16_t dst_x;
    uint16_t enabled;
    struct MARV MARV;

First "true" field is at offset 0x48 while looking at decomp. Layer definition inside XimrContext start at the same offsets and seems to have the same structure.
Layers data is located at the same Ximr Context offsets as 200D/Digic 7.

Output Chunk is defined at different offset in Ximr Context (start at 0x28 on M10, 0xC on 200D).

Interesting part - there's a condition on which 3rd layer is referenced:
Code: [Select]
XimrSetLayerVisibility(XimrContext,2,1);
XimrSetLayer_related_fc3edc68(XimrContext,2,0,2,*param_5);

If you are able to patch this function and inject some instructions, you should be able to add own layer like this:
Code: [Select]
XimrSetLayer_related_fc3edc30(XimrContext,0,0,3,0);
XimrSetLayerVisibility(XimrContext,0,1);
XimrSetLayerColorParams(XimrContext,0,pNewLayerMARV,colorId,0); //colorId is probably just 1
XimrSetLayerMARV(XimrContext,0,pNewLayerMARV,p4);
XimrSetLayerDimensions(XimrContext,0,0,0,src_x, src_y, src_w, src_h, dst_x, dst_y);

Please remember than on 200D (Digic 7) I had to align display buffer to 0x100, otherwise it was shifted by offset/4. This wasn't the case on R/Digic 8.
Other potential candidates to hook: very end of XimrInitializeContext, very beginning of XimrExe (before mzrm_createmessage).

I would just copy all parameters from layer 0/1, except pNewLayerMARV which you need to create yourself. In my experiments I created the structure myself, but there's a CreateMARV function you may try to use at fc586110:
Code: [Select]
MARV * CreateMARV (void * p1, uint32_t flags, uint width, uint height, uint p5, uint p6)
I never dug into functions that are not responsible for layers, except naming some of those. Goal was to add own layers, and those XimrSetLayer_* were enough to achieve that on 200D.
« Last Edit: 13 / April / 2021, 02:42:20 by kitor »
Magic Lantern / EOS R / 200D

*

Offline srsa_4c

  • ******
  • 4393
Re: Display (bitmap overlay)
« Reply #176 on: 18 / April / 2021, 14:47:28 »
First of all, thanks for sharing all this information.
I would just copy all parameters from layer 0/1
I did just that, copied the layer 1 descriptor to layer 3, inside the ximr struct. Then, I patched a few members in the layer struct (without calling any of the ximr functions). I intercepted the ximr struct in the function that sends the ximrexe message. I used the protection region trick for the experiment, but for a production version I'd patch the dry_memcpy function instead.
I left the pixel format as is, so the demo layer was rgba. It's looking very pretty, but we'd have to find 1.3MB RAM for a 720x480 buffer. If I see it correctly, upscaling of layers is not possible.

*

Offline kitor

  • *
  • 18
Re: Display (bitmap overlay)
« Reply #177 on: 18 / April / 2021, 15:00:50 »
So it works, nice  :)

Using ximr stubs should be "universal" for different Zico firmwares. As you already found, those differ in two examples you provided - but Ximr* functions may provide universal interface (those from M10 were on par with 200D/R)

On Digic 8 I was able to create 720x480 layer while Canon code used 960x540 layers. So it covered only "visible area". With caveats, but those were directly related to XCM / refreshVrmsSurface implementation specific for EOS R only.
« Last Edit: 18 / April / 2021, 15:04:15 by kitor »
Magic Lantern / EOS R / 200D


*

Offline philmoz

  • *****
  • 3275
    • Photos
Re: Display (bitmap overlay)
« Reply #178 on: 20 / April / 2021, 03:56:23 »
Thanks @kitor and @srsa_4c - this is very cool  :)

Based on the M10 info I was able to duplicate this on the G5X using an RGBA buffer allocated from EXMEM.

Edit: I patched dry_memcpy as srsa_4c suggested in order to modify the layer structure.

Edit2: On the G5X the RBGA bitmap visible area is always 720 pixels wide for the LCD, EVF and HDMI displays (whereas the YUV output varies from 720 when using the LCD up to 1024 for HDMI). The LCD and HDMI buffers are both 480 rows high, the EVF is 540.

Phil.



« Last Edit: 20 / April / 2021, 07:08:56 by philmoz »
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

*

Offline philmoz

  • *****
  • 3275
    • Photos
Re: Display (bitmap overlay)
« Reply #179 on: 21 / April / 2021, 19:18:45 »
I've been playing with this on the G5X and G7X2 and found some strangeness when using HDMI output.


The RGBA layers are not full screen when using HDMI, they are smaller and centered (affects Canon UI as well).
This would affect zebra and edge overlay if we used an RGBA layer for the CHDK UI, as the pixels in the two frames are not aligned.


If transfer_src_overlay is called to refresh the RGBA layer while the camera is switching from LCD to HDMI out, it will crash.


Additional RGBA layers are rendered twice when using HDMI. They are rendered once at the RGBA frame size and again at the YUV frame size on the screen. The attached image shows this - only two blue boxes were drawn into the RGBA layer. This may also be happening when using the LCD; but is not visible because the frames are the same size.


Phil.

CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

 

Related Topics