Alpha blending of canvas on top of video looks wrong

Hello,

We have been experimenting with porting a native c++ application to webassembly. We’re using our own UI framework, which uses OpenGL for rendering. We have currently set up a canvas, which renders the application UI, and an html video element behind the canvas, so that our UI is rendered on top of the video. This setup works as expected in a web browser on our host pc (and on a TV running Tizen OS) . However, when ran as a packaged web app on WebOS, semi transparent content is incorrectly blended with the video element as soon as playback starts. It appears as if UI elements with semi transparant alpha values become even more transparent when video starts playing and thus when the canvas gets composited on top of the video plane.

I’ve already tried playing with things like the css mix-blend-mode, but these have no effect at all in the composition of the canvas. The opengl context is also set to pre multiplied alpha already. Disabling makes it worse.

Is there documentation somewhere regarding this topic or can someone guide me in the correct direction?

Thank you

webOS TV uses different web engines depending on the webOS version. Please check compatibility with the web engine first. Thank you.

Hello,

The issue occurs on multiple LG TV models. The latest model we have tested that exhibits the issue is:

Model: OLED55C54LA
webOS version: webOS 25 / 10.3.0-2502
Web engine: Chromium 120

I checked the document you linked, but I could not find any information there regarding how the video layer is composited with other HTML/canvas elements.

I have also reproduced the issue in isolation with a minimal standalone example. This example does not use WebGL, OpenGL, WebAssembly, or our own UI framework. It only uses an HTML5 <video> element with a 2D <canvas> positioned on top.

<!DOCTYPE html>
<html>

<head>
  <style>
    .video-wrapper {
      position: relative;
      width: 600px;
    }

    video {
      width: 100%;
      display: block;
    }

    canvas {
      position: absolute;
      left: 0;
      top: 0;
      pointer-events: none;
    }
  </style>
</head>

<body>

  <h2>Canvas on top of video</h2>

  <div class="video-wrapper">
    <video id="myVideo" controls autoplay muted loop>
      <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
    </video>

    <canvas id="myCanvas"></canvas>
  </div>

  <script>
    const video = document.getElementById("myVideo");
    const canvas = document.getElementById("myCanvas");
    const ctx = canvas.getContext("2d");

    function resizeCanvas() {
      canvas.width = video.clientWidth;
      canvas.height = video.clientHeight;
      drawRectangle();
    }

    function drawRectangle() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      const rectX = 100;
      const rectY = 80;
      const rectW = 250;
      const rectH = 150;

      // Transparent red rectangle
      ctx.fillStyle = "rgba(255, 0, 0, 0.35)";
      ctx.fillRect(rectX, rectY, rectW, rectH);

      // Optional border
      ctx.strokeStyle = "red";
      ctx.lineWidth = 3;
      ctx.strokeRect(rectX, rectY, rectW, rectH);

      // Semi-transparent white text centered inside the rectangle
      ctx.fillStyle = "rgba(255, 255, 255, 0.50)";
      ctx.font = "bold 28px monospace";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.fillText("Test", rectX + rectW / 2, rectY + rectH / 2);
    }

    video.addEventListener("loadedmetadata", resizeCanvas);
    window.addEventListener("resize", resizeCanvas);
  </script>

</body>

</html>

The example draws a semi-transparent red rectangle and semi-transparent white text on top of the video.

This looks correct in desktop browsers and on other TV platforms. However, on multiple LG TV models, the rectangle and text appear too muted/dull, as if the alpha blending is incorrect. As mentioned before, this only occurs when the video is actually playing. It is not just caused by the presence of the <video> element.

Because the issue is reproducible with a simple 2D canvas overlay, this does not appear to be related to our OpenGL/WebGL blending state or to WebAssembly. It looks more like a compositing issue between the active video layer and the canvas/DOM layer.

Can you confirm whether the HTML5 video element in packaged webOS TV apps is rendered using a separate hardware/native video plane? If so, are there any documented limitations or required settings for compositing semi-transparent canvas or DOM content over that video plane?

Thank you.

In the webOS TV, the video area becomes transparent and the video is rendered on a separate layer. Please try adding a background area. Thank you.