Changeset 63502 in webkit


Ignore:
Timestamp:
Jul 15, 2010 6:00:28 PM (14 years ago)
Author:
zmo@google.com
Message:

2010-07-13 Zhenyao Mo <zmo@google.com>

Reviewed by Nate Chapin.

WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719

  • src/GraphicsContext3D.cpp: (WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas(). (WebCore::GraphicsContext3DInternal::beginPaint): Just use paintRenderingResultsToCanvas().

2010-07-13 Zhenyao Mo <zmo@google.com>

Reviewed by Nate Chapin.

WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719

Tests: fast/canvas/webgl/canvas-test.html

fast/canvas/webgl/gl-pixelstorei.html

  • html/HTMLCanvasElement.cpp: (WebCore::HTMLCanvasElement::makeRenderingResultsAvailable): Paint the WebGL rendering results to canvas if it's 3d. (WebCore::HTMLCanvasElement::toDataURL): Paint the WebGL rendering results to canvas if it's 3d.
  • html/canvas/CanvasRenderingContext2D.cpp: (WebCore::CanvasRenderingContext2D::drawImage): Paint the WebGL rendering results to canvas if it's 3d before drawing.
  • html/canvas/WebGLRenderingContext.cpp: (WebCore::WebGLRenderingContext::markContextChanged): Mark it always for canvas2d.drawImage purpose. (WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas): Paint the WebGL rendering results to canvas if it's dirty.
  • html/canvas/WebGLRenderingContext.h: Declare paintRenderingResultsToCanvas().
  • platform/graphics/GraphicsContext3D.h: Declare paintRenderingResultsToCanvas() & paintToCanvas().
  • platform/graphics/cg/GraphicsContext3DCG.cpp: (WebCore::GraphicsContext3D::paintToCanvas): Paint the rendered image pixels to the canvas.
  • platform/graphics/mac/GraphicsContext3DMac.mm: (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
  • platform/graphics/qt/GraphicsContext3DQt.cpp: (WebCore::GraphicsContext3D::beginPaint): Just call paintRenderingResultsToCanvas(). (WebCore::GraphicsContext3D::endPaint): (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().

2010-07-13 Zhenyao Mo <zmo@google.com>

Reviewed by Nate Chapin.

WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719

  • fast/canvas/webgl/canvas-test-expected.txt: Added.
  • fast/canvas/webgl/canvas-test.html: Added.
  • fast/canvas/webgl/gl-pixelstorei-expected.txt: Added.
  • fast/canvas/webgl/gl-pixelstorei.html: Added.
Location:
trunk
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r63501 r63502  
     12010-07-13  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Nate Chapin.
     4
     5        WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
     6        https://bugs.webkit.org/show_bug.cgi?id=34719
     7
     8        * fast/canvas/webgl/canvas-test-expected.txt: Added.
     9        * fast/canvas/webgl/canvas-test.html: Added.
     10        * fast/canvas/webgl/gl-pixelstorei-expected.txt: Added.
     11        * fast/canvas/webgl/gl-pixelstorei.html: Added.
     12
    1132010-07-15  Ojan Vafai  <ojan@chromium.org>
    214
  • trunk/WebCore/ChangeLog

    r63494 r63502  
     12010-07-13  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Nate Chapin.
     4
     5        WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
     6        https://bugs.webkit.org/show_bug.cgi?id=34719
     7
     8        Tests: fast/canvas/webgl/canvas-test.html
     9               fast/canvas/webgl/gl-pixelstorei.html
     10
     11        * html/HTMLCanvasElement.cpp:
     12        (WebCore::HTMLCanvasElement::makeRenderingResultsAvailable): Paint the WebGL rendering results to canvas if it's 3d.
     13        (WebCore::HTMLCanvasElement::toDataURL): Paint the WebGL rendering results to canvas if it's 3d.
     14        * html/canvas/CanvasRenderingContext2D.cpp:
     15        (WebCore::CanvasRenderingContext2D::drawImage): Paint the WebGL rendering results to canvas if it's 3d before drawing.
     16        * html/canvas/WebGLRenderingContext.cpp:
     17        (WebCore::WebGLRenderingContext::markContextChanged): Mark it always for canvas2d.drawImage purpose.
     18        (WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas): Paint the WebGL rendering results to canvas if it's dirty.
     19        * html/canvas/WebGLRenderingContext.h: Declare paintRenderingResultsToCanvas().
     20        * platform/graphics/GraphicsContext3D.h: Declare paintRenderingResultsToCanvas() & paintToCanvas().
     21        * platform/graphics/cg/GraphicsContext3DCG.cpp:
     22        (WebCore::GraphicsContext3D::paintToCanvas): Paint the rendered image pixels to the canvas.
     23        * platform/graphics/mac/GraphicsContext3DMac.mm:
     24        (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
     25        * platform/graphics/qt/GraphicsContext3DQt.cpp:
     26        (WebCore::GraphicsContext3D::beginPaint): Just call paintRenderingResultsToCanvas().
     27        (WebCore::GraphicsContext3D::endPaint):
     28        (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
     29
    1302010-07-15  Nico Weber  <thakis@chromium.org>
    231
  • trunk/WebCore/html/HTMLCanvasElement.cpp

    r63219 r63502  
    298298#endif
    299299
     300void HTMLCanvasElement::makeRenderingResultsAvailable()
     301{
     302#if ENABLE(3D_CANVAS)
     303    if (is3D()) {
     304        WebGLRenderingContext* context3d = reinterpret_cast<WebGLRenderingContext*>(renderingContext());
     305        context3d->paintRenderingResultsToCanvas();
     306    }
     307#endif
     308}
     309
    300310void HTMLCanvasElement::recalcStyle(StyleChange change)
    301311{
     
    327337
    328338    String lowercaseMimeType = mimeType.lower();
     339
     340    makeRenderingResultsAvailable();
    329341
    330342    // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
  • trunk/WebCore/html/HTMLCanvasElement.h

    r63025 r63502  
    3232#include "HTMLElement.h"
    3333#include "IntSize.h"
    34 
    35 #if ENABLE(3D_CANVAS)   
    36 #include "GraphicsContext3D.h"
    37 #endif
    3834
    3935namespace WebCore {
     
    115111#endif
    116112
     113    void makeRenderingResultsAvailable();
     114
    117115private:
    118116    HTMLCanvasElement(const QualifiedName&, Document*);
  • trunk/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r63382 r63502  
    11581158        canvas()->setOriginTainted();
    11591159
     1160    sourceCanvas->makeRenderingResultsAvailable();
     1161
    11601162    c->drawImage(buffer->image(), DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
    11611163    willDraw(destRect); // This call comes after drawImage, since the buffer we draw into may be our own, and we need to make sure it is dirty.
  • trunk/WebCore/html/canvas/WebGLRenderingContext.cpp

    r63460 r63502  
    142142    if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
    143143        renderBox->layer()->rendererContentChanged();
    144     else {
    145144#endif
    146         if (!m_markedCanvasDirty) {
    147             // Make sure the canvas's image buffer is allocated.
    148             canvas()->buffer();
    149             canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
    150             m_markedCanvasDirty = true;
    151         }
    152 #if USE(ACCELERATED_COMPOSITING)
    153     }
    154 #endif
     145    if (!m_markedCanvasDirty) {
     146        // Make sure the canvas's image buffer is allocated.
     147        canvas()->buffer();
     148        canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
     149        m_markedCanvasDirty = true;
     150    }
     151}
     152
     153bool WebGLRenderingContext::paintRenderingResultsToCanvas()
     154{
     155    if (m_markedCanvasDirty) {
     156        m_markedCanvasDirty = false;
     157        m_context->paintRenderingResultsToCanvas(this);
     158        return true;
     159    }
     160    return false;
    155161}
    156162
  • trunk/WebCore/html/canvas/WebGLRenderingContext.h

    r63253 r63502  
    307307        void reshape(int width, int height);
    308308
     309        // Return value true indicates canvas is updated during the call,
     310        // false indicates no updates.
     311        bool paintRenderingResultsToCanvas();
     312
    309313        // Helpers for notification about paint events.
    310314        void beginPaint();
  • trunk/WebCore/platform/graphics/GraphicsContext3D.h

    r63224 r63502  
    6767typedef int Platform3DObject;
    6868const Platform3DObject NullPlatform3DObject = 0;
     69#endif
     70
     71#if PLATFORM(CG)
     72#include <CoreGraphics/CGContext.h>
    6973#endif
    7074
     
    711715
    712716        void reshape(int width, int height);
    713        
     717
     718#if PLATFORM(CG)
     719        void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
     720                           int canvasWidth, int canvasHeight, CGContextRef context);
     721#endif
     722
     723        void paintRenderingResultsToCanvas(WebGLRenderingContext* context);
     724
    714725        // Helpers for notification about paint events
    715726        void beginPaint(WebGLRenderingContext* context);
  • trunk/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp

    r62145 r63502  
    3636#include <CoreGraphics/CGContext.h>
    3737#include <CoreGraphics/CGImage.h>
     38
     39#include <wtf/RetainPtr.h>
    3840
    3941namespace WebCore {
     
    105107}
    106108
     109void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, CGContextRef context)
     110{
     111    if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
     112        return;
     113    int rowBytes = imageWidth * 4;
     114    RetainPtr<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(0, imagePixels, rowBytes * imageHeight, 0);
     115    RetainPtr<CGColorSpaceRef> colorSpace = CGColorSpaceCreateDeviceRGB();
     116    RetainPtr<CGImageRef> cgImage = CGImageCreate(imageWidth,
     117                                                  imageHeight,
     118                                                  8,
     119                                                  32,
     120                                                  rowBytes,
     121                                                  colorSpace.get(),
     122                                                  kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
     123                                                  dataProvider.get(),
     124                                                  0,
     125                                                  false,
     126                                                  kCGRenderingIntentDefault);
     127    // CSS styling may cause the canvas's content to be resized on
     128    // the page. Go back to the Canvas to figure out the correct
     129    // width and height to draw.
     130    CGRect rect = CGRectMake(0, 0,
     131                             canvasWidth,
     132                             canvasHeight);
     133    // We want to completely overwrite the previous frame's
     134    // rendering results.
     135    CGContextSaveGState(context);
     136    CGContextSetBlendMode(context,
     137                          kCGBlendModeCopy);
     138    CGContextSetInterpolationQuality(context,
     139                                     kCGInterpolationNone);
     140    CGContextDrawImage(context,
     141                       rect, cgImage.get());
     142    CGContextRestoreGState(context);
     143}
    107144
    108145} // namespace WebCore
  • trunk/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm

    r63224 r63502  
    4040#include "Float32Array.h"
    4141#include "WebGLFramebuffer.h"
     42#include "GraphicsContext.h"
     43#include "HTMLCanvasElement.h"
    4244#include "Int32Array.h"
    4345#include "WebGLLayer.h"
    4446#include "WebGLProgram.h"
    4547#include "WebGLRenderbuffer.h"
     48#include "WebGLRenderingContext.h"
    4649#include "WebGLShader.h"
    4750#include "WebGLTexture.h"
     
    236239{
    237240    CGLSetCurrentContext(m_contextObj);
     241}
     242
     243void GraphicsContext3D::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
     244{
     245    HTMLCanvasElement* canvas = context->canvas();
     246    ImageBuffer* imageBuffer = canvas->buffer();
     247
     248    int rowBytes = m_currentWidth * 4;
     249    int totalBytes = rowBytes * m_currentHeight;
     250
     251    OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]);
     252    if (!pixels)
     253        return;
     254
     255    CGLSetCurrentContext(m_contextObj);
     256
     257    bool mustRestoreFBO;
     258    if (m_attrs.antialias) {
     259        ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     260        ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     261        ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     262        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     263        mustRestoreFBO = true;
     264    } else {
     265        if (m_boundFBO != m_fbo) {
     266            mustRestoreFBO = true;
     267            ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     268        }
     269    }
     270
     271    GLint packAlignment = 4;
     272    bool mustRestorePackAlignment = false;
     273    ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
     274    if (packAlignment > 4) {
     275        ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
     276        mustRestorePackAlignment = true;
     277    }
     278
     279    ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get());
     280
     281    if (mustRestorePackAlignment)
     282        ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
     283
     284    if (mustRestoreFBO)
     285        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     286
     287    paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
     288                  canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
    238289}
    239290
  • trunk/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp

    r62145 r63502  
    522522void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
    523523{
     524    paintRenderingResultsToCanvas();
     525}
     526
     527void GraphicsContext3D::endPaint()
     528{
     529}
     530
     531void GraphicsContext3D::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
     532{
    524533    m_internal->m_glWidget->makeCurrent();
    525534    HTMLCanvasElement* canvas = context->canvas();
     
    527536    QPainter* painter = imageBuffer->context()->platformContext();
    528537    paint(painter, QRect(QPoint(0, 0), QSize(m_currentWidth, m_currentHeight)));
    529 }
    530 
    531 void GraphicsContext3D::endPaint()
    532 {
    533538}
    534539
  • trunk/WebKit/chromium/ChangeLog

    r63495 r63502  
     12010-07-13  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Nate Chapin.
     4
     5        WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
     6        https://bugs.webkit.org/show_bug.cgi?id=34719
     7
     8        * src/GraphicsContext3D.cpp:
     9        (WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
     10        (WebCore::GraphicsContext3DInternal::beginPaint): Just use paintRenderingResultsToCanvas().
     11
    1122010-07-15  Victor Wang  <victorw@chromium.org>
    213
  • trunk/WebKit/chromium/src/GraphicsContext3D.cpp

    r63224 r63502  
    113113    void reshape(int width, int height);
    114114
     115    void paintRenderingResultsToCanvas(WebGLRenderingContext* context);
    115116    void beginPaint(WebGLRenderingContext* context);
    116117    void endPaint();
     
    400401#endif
    401402
    402 void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
     403void GraphicsContext3DInternal::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
    403404{
    404405    HTMLCanvasElement* canvas = context->canvas();
     
    450451    }
    451452#elif PLATFORM(CG)
    452     if (m_renderOutput) {
    453         int rowBytes = m_impl->width() * 4;
    454         CGDataProviderRef dataProvider = CGDataProviderCreateWithData(0, m_renderOutput, rowBytes * m_impl->height(), 0);
    455         CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    456         CGImageRef cgImage = CGImageCreate(m_impl->width(),
    457                                            m_impl->height(),
    458                                            8,
    459                                            32,
    460                                            rowBytes,
    461                                            colorSpace,
    462                                            kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
    463                                            dataProvider,
    464                                            0,
    465                                            false,
    466                                            kCGRenderingIntentDefault);
    467         // CSS styling may cause the canvas's content to be resized on
    468         // the page. Go back to the Canvas to figure out the correct
    469         // width and height to draw.
    470         CGRect rect = CGRectMake(0, 0,
    471                                  context->canvas()->width(),
    472                                  context->canvas()->height());
    473         // We want to completely overwrite the previous frame's
    474         // rendering results.
    475         CGContextSetBlendMode(imageBuffer->context()->platformContext(),
    476                               kCGBlendModeCopy);
    477         CGContextSetInterpolationQuality(imageBuffer->context()->platformContext(),
    478                                          kCGInterpolationNone);
    479         CGContextDrawImage(imageBuffer->context()->platformContext(),
    480                            rect, cgImage);
    481         CGImageRelease(cgImage);
    482         CGColorSpaceRelease(colorSpace);
    483         CGDataProviderRelease(dataProvider);
    484     }
     453    if (m_renderOutput)
     454        context->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(),
     455                                                    canvas->width(), canvas->height(),
     456                                                    imageBuffer->context()->platformContext());
    485457#else
    486458#error Must port to your platform
    487459#endif
     460}
     461
     462void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
     463{
     464    paintRenderingResultsToCanvas(context);
    488465}
    489466
     
    13261303DELEGATE_TO_INTERNAL_4(viewport, long, long, unsigned long, unsigned long)
    13271304
     1305DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, WebGLRenderingContext*)
    13281306DELEGATE_TO_INTERNAL_1(beginPaint, WebGLRenderingContext*)
    13291307DELEGATE_TO_INTERNAL(endPaint)
Note: See TracChangeset for help on using the changeset viewer.