Bug 41353 - [Qt] CSS masks on images should not cause QPixmap "texture upload"
Summary: [Qt] CSS masks on images should not cause QPixmap "texture upload"
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Other Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords: Performance, Qt, QtTriaged
Depends on:
Blocks:
 
Reported: 2010-06-29 07:47 PDT by Kimmo Kinnunen
Modified: 2012-07-11 13:27 PDT (History)
5 users (show)

See Also:


Attachments
Testcase demonstrating texture uploads caused by using css mask image (21.30 KB, application/x-zip-compressed)
2010-06-29 07:47 PDT, Kimmo Kinnunen
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kimmo Kinnunen 2010-06-29 07:47:16 PDT
Created attachment 60020 [details]
Testcase demonstrating texture uploads caused by using css mask image

QtWebKit should avoid creating an extra QPixmap when painting an image with CSS mask. This is slow with raster graphicssystem, and on some architectures we are forced to use raster.

Assume following:
  * QtWebKit QGraphicsWebView scrolling (e.g. using QWebFrame::setScrollPosition, not resizesToContent)
  * No tiling
  * Running app with -graphicssystem raster
  * GraphicsView is backed by a QGLWidget

In this setting, QtWebKit gets a QPainter that's created from QGLWidget.

If I've understood correctly, painting images with CSS masks, for example with "-webkit-mask-box-image", will cause following paint pattern:
 0. With image (a) defined in HTML IMG tag
 0. With mask image (m) and defined in CSS 
 1. Passed in QPainter (p) (backed by QGLWidget)
 2. Create new QPixmap (b) (RenderLayer::paintLayer calls GraphicsContext::beginTransparencyLayer)
 3. Paint the image (a) to (b)
 4. Paint the mask (m) with proper composition flags to (b)
 5. Paint the layer (b) to (p)

Raster image will be generated in in points 2 and 3.
"Upload" of the raster image to GL image will be done in (5).

Here "upload" means that implicit texture upload / similar conversion that is done when a QPixmap that is really backed by QImage is transformed in such a way that it is fast to paint with the QPainter. In this setting, the process is GL texture upload, which is relatively slow.

For such a simple cases, it would be great if QtWebKit would not resort to raster path. If the masks are painted using the raster path, then the texture upload cannot be avoided. In practice it is impossible to guarantee any sort of fast frame updates if texture uploads occur. 

Attached you can find a test-case that demonstrates the problem. You should be able to scroll the page and observe the texture uploads, if you have the tool to do so.

If you do not, then the test-case can be used to indirectly pin-point the bad behavior. The test-case can be run with two modes:
 "basic mode": ./yourwebkitapp -graphicssystem raster file://home/user/index.html
 "nosense mode": ./yourwebkitapp -graphicssystem raster "file://home/user/index.html#a"
  
"basic mode" shows masked icons that can be scrolled. You can measure the scroll FPS.

The "nosense" mode is the exactly same test-case, except that the containing div of the icons has "opacity:0.9" rule. 

Even though the "nosense" mode is more graphically intensive (judging by common sense), it will have higher FPS values when scrolled. I think this should be attributed to the lack of texture uploads per image. The opacity of containing div will force the containing div to be the QPixmap layer, which will result in one (bigger) texture upload. AFAIK opacity should not trigger accelerated compositing feature on.

In graphicssystems that properly support painting to offscreen pixmaps this is not a problem. With Qt and raster it is.

Ideas to fix (with current restrictions):
GraphicsContext::beginTransparencyLayer could be maybe modified to notice simple cases that occur when the layers are only used for masking. I'm not sure this would work in practice..
Comment 1 Antti Koivisto 2010-06-29 09:21:56 PDT
Yeah, sounds like this could be optimized for simple transparency layers, perhaps cross-platform too.
Comment 2 Noam Rosenthal 2010-07-01 10:12:37 PDT
I'm working on masks for the AC with OpenGL code path; However I'm not sure if that fits this use case.
Comment 3 Noam Rosenthal 2012-07-11 13:27:15 PDT
The whole graphics architecture for masks has changed. I any case if a similar problem still exists it deserves a new bug report.