Bug 28018

Summary: Need to implement Canvas3d/WebGL for 3D rendering
Product: WebKit Reporter: Chris Marrin <cmarrin>
Component: WebGLAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: dglazkov, dino, eric.carlson, fishd, hyatt, kbr, krit, laszlo.gombos, mario.bensi, ml, oliver, sam, simon.fraser, vangelis
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
Attachments:
Description Flags
Patch 1 of 4: Add ENABLE_3D_CANVAS flag to the build
hyatt: review+
Patch 2 of 4: New Canvas 3D files
oliver: review-
Patch 3 of 4: Adding new files to the build
oliver: review+
Patch 4 of 4: Connect everything up
simon.fraser: review-
Patch for new Canvas3D files
oliver: review+
Patch with new GL Object files
oliver: review+
Patch with remaining new files
simon.fraser: review+
Patch to add Canvas3D files to build
oliver: review+
Replacement patch to add Canvas3D files to build
none
One more replacement patch to add Canvas3D files to build
simon.fraser: review+
Patch with Platform specific rendering changes for Canvas3D
none
Final patch for Canvas3D work simon.fraser: review-

Chris Marrin
Reported 2009-08-05 06:11:49 PDT
This bug is the placeholder for the WebGL patches. WebGL is a Khronos effort to add a 3D rendering context to the Canvas element. The API is compatible with OpenGL ES 2.0. The spec is not yet public, so this implementation is subject to change as the spec evolves. The first implementation will be a fairly complete implementation of ES 2.0, and will support Image and Canvas image sources.
Attachments
Patch 1 of 4: Add ENABLE_3D_CANVAS flag to the build (6.52 KB, patch)
2009-08-05 10:24 PDT, Chris Marrin
hyatt: review+
Patch 2 of 4: New Canvas 3D files (244.72 KB, patch)
2009-08-05 10:36 PDT, Chris Marrin
oliver: review-
Patch 3 of 4: Adding new files to the build (38.18 KB, patch)
2009-08-05 10:51 PDT, Chris Marrin
oliver: review+
Patch 4 of 4: Connect everything up (30.91 KB, patch)
2009-08-05 11:03 PDT, Chris Marrin
simon.fraser: review-
Patch for new Canvas3D files (165.97 KB, patch)
2009-08-21 12:11 PDT, Chris Marrin
oliver: review+
Patch with new GL Object files (54.08 KB, patch)
2009-08-21 17:52 PDT, Chris Marrin
oliver: review+
Patch with remaining new files (16.89 KB, patch)
2009-08-23 16:32 PDT, Chris Marrin
simon.fraser: review+
Patch to add Canvas3D files to build (56.15 KB, patch)
2009-08-24 09:47 PDT, Chris Marrin
oliver: review+
Replacement patch to add Canvas3D files to build (66.83 KB, patch)
2009-08-25 09:29 PDT, Chris Marrin
no flags
One more replacement patch to add Canvas3D files to build (73.90 KB, patch)
2009-08-25 10:15 PDT, Chris Marrin
simon.fraser: review+
Patch with Platform specific rendering changes for Canvas3D (10.42 KB, patch)
2009-08-25 16:49 PDT, Chris Marrin
no flags
Final patch for Canvas3D work (31.90 KB, patch)
2009-08-27 06:39 PDT, Chris Marrin
simon.fraser: review-
Chris Marrin
Comment 1 2009-08-05 10:24:08 PDT
Created attachment 34145 [details] Patch 1 of 4: Add ENABLE_3D_CANVAS flag to the build
Chris Marrin
Comment 2 2009-08-05 10:36:53 PDT
Created attachment 34146 [details] Patch 2 of 4: New Canvas 3D files
Chris Marrin
Comment 3 2009-08-05 10:51:27 PDT
Created attachment 34149 [details] Patch 3 of 4: Adding new files to the build
Chris Marrin
Comment 4 2009-08-05 11:03:43 PDT
Created attachment 34151 [details] Patch 4 of 4: Connect everything up
Dave Hyatt
Comment 5 2009-08-05 11:11:13 PDT
Comment on attachment 34145 [details] Patch 1 of 4: Add ENABLE_3D_CANVAS flag to the build r=me
Oliver Hunt
Comment 6 2009-08-05 12:11:48 PDT
Comment on attachment 34146 [details] Patch 2 of 4: New Canvas 3D files > +static inline PassRefPtr<CanvasNumberArray> toCanvasNumberArray(JSC::ExecState* exec, const JSValue& value) This is fairly inefficient, and will allow non-array types, eg: toCanvasArray({length:5}) will produce a CanvasFloatArray of 5 NaNs > +{ > + if (!value.isObject()) > + return 0; > + > + JSObject* array = asObject(value); > + int length = array->get(exec, Identifier(exec, "length")).toInt32(exec); > + RefPtr<CanvasNumberArray> numberArray = CanvasNumberArray::create(length); > + for (int i = 0; i < length; ++i) { > + float value = array->get(exec, i).toFloat(exec); Because this is a generic accessor function (and because toFloat may throw) you need: JSValue v = array->get(exec, i); if (exec->hadException()) return 0; float value = v.toFloat(exec); if (exec->hadException()) return 0; > + numberArray->data()[i] = value; > + } > + > + return numberArray; > +} If you disallow non-array types (i'm not sure if you want to do this or not) then you can devirtualise and remove the get > + > +JSValue JSCanvasRenderingContext3D::glBufferData(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned target = args.at(0).toInt32(exec); > + unsigned usage = args.at(2).toInt32(exec); These may throw -- and the values are untrusted (they may not even be present) > + RefPtr<CanvasNumberArray> numberArray = toCanvasNumberArray(exec, args.at(1)); numberArray may be null where is this handled? > + > +JSValue JSCanvasRenderingContext3D::glBufferSubData(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned target = args.at(0).toInt32(exec); > + unsigned offset = args.at(1).toInt32(exec); ditto > +JSValue JSCanvasRenderingContext3D::glVertexAttrib(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned indx = args.at(0).toInt32(exec); ditto > +// void glVertexAttribPointer (in unsigned long indx, in long size, in unsigned long type, in boolean normalized, in unsigned long stride, in CanvasNumberArray array); > +JSValue JSCanvasRenderingContext3D::glVertexAttribPointer(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned indx = args.at(0).toInt32(exec); > + unsigned size = args.at(1).toInt32(exec); > + unsigned type = args.at(2).toInt32(exec); > + unsigned normalized = args.at(3).toInt32(exec); > + bool stride = args.at(4).toBoolean(exec); ditto > +JSValue JSCanvasRenderingContext3D::glUniformMatrix(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned location = args.at(0).toInt32(exec); > + unsigned count = args.at(1).toInt32(exec); > + bool transpose = args.at(2).toBoolean(exec); > + ditto > + if (!args.at(3).isObject()) > + return jsUndefined(); > + > + WebKitCSSMatrix* matrix = toWebKitCSSMatrix(args.at(3)); > + if (matrix) > + impl()->glUniformMatrix(location, transpose, matrix); > + else { > + JSObject* array = asObject(args.at(3)); Same as before are you sure we want to allow non-array arguments? > +JSValue JSCanvasRenderingContext3D::glUniformf(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned location = args.at(0).toInt32(exec); > + > + switch(args.size()) { > + case 2: > + if (args.at(1).isObject()) { > + RefPtr<CanvasNumberArray> numberArray = toCanvasNumberArray(exec, args.at(1)); > + impl()->glUniform(location, numberArray.get()); > + } > + else > + impl()->glUniform(location, (float) args.at(1).toNumber(exec)); toNumber may throw, should be using a C++ cast (woo! a style comment! that'll annoy smfr :D) > + break; > + case 3: > + impl()->glUniform(location, (float) args.at(1).toNumber(exec), > + (float) args.at(2).toNumber(exec)); > + break; > + case 4: > + impl()->glUniform(location, (float) args.at(1).toNumber(exec), > + (float) args.at(2).toNumber(exec), > + (float) args.at(3).toNumber(exec)); > + break; > + case 5: > + impl()->glUniform(location, (float) args.at(1).toNumber(exec), > + (float) args.at(2).toNumber(exec), > + (float) args.at(3).toNumber(exec), > + (float) args.at(4).toNumber(exec)); > + break; You should probably throw an exception if the numbe rof arguments doesn't match any expected count. > +JSValue JSCanvasRenderingContext3D::glUniformi(JSC::ExecState* exec, JSC::ArgList const& args) > +{ Same as before, i really wish we have auto codegen for variadic arguments > +JSValue JSCanvasRenderingContext3D::glDrawElements(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned mode = args.at(0).toInt32(exec); > + unsigned type = args.at(1).toInt32(exec); > + > + unsigned int count = 0; > + > + // If the third param is not an object, it is a number, which is the count. > + // In this case if there is a 4th param, it is the offset. If there is no > + // 4th param, the offset is 0 > + if (!args.at(2).isObject()) { > + count = args.at(2).toInt32(exec); > + unsigned int offset = (args.size() > 3) ? args.at(3).toInt32(exec) : 0; > + impl()->glDrawElements(mode, count, type, (void*) offset); > + } else { > + void* passedIndices = 0; passedIndices should just be an OwnFastMallocPtr, and you should use fastMalloc in place of malloc. It would be better if you used tryFastMalloc, and null check the result so we don't crash if malloc fails. > + JSObject* array = asObject(args.at(2)); > + count = array->get(exec, Identifier(exec, "length")).toInt32(exec); > + > + if (type == GL_UNSIGNED_BYTE) { > + unsigned char* indices = (unsigned char*) malloc(count * sizeof(unsigned short)); fastmAlloc should be used instead of malloc, also should use c style cast. > + } else if (type == GL_UNSIGNED_SHORT) { > + unsigned short* indices = (unsigned short*) malloc(count * sizeof(unsigned short)); ditto > + } else TypeError should be thrown on argument mismatch > + return jsUndefined(); > + > + impl()->glDrawElements(mode, count, type, passedIndices); > + free(passedIndices); OwnFastMallocPtr saves manually calling free > + } > + > + return jsUndefined(); > +} > + > +// void texImage2DHTML(in unsigned long target, in unsigned long level, in HTMLImageElement image); > +JSValue JSCanvasRenderingContext3D::texImage2D(ExecState* exec, const ArgList& args) > +{ > + CanvasRenderingContext3D* context = impl(); > + unsigned target = args.at(0).toInt32(exec); > + unsigned level = args.at(1).toInt32(exec); exception and untrusted args again > + > + // The image parameter can be a <img> or <canvas> element. > + JSValue value = args.at(2); > + if (!value.isObject()) > + return throwError(exec, TypeError); > + JSObject* o = asObject(value); > + > + ExceptionCode ec = 0; > + if (o->inherits(&JSHTMLImageElement::s_info)) { > + HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); > + context->texImage2D(target, level, imgElt, ec); > + } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { > + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); > + context->texImage2D(target, level, canvas, ec); <video> should also be allowed here > +// void texSubImage2DHTML(in unsigned long target, in unsigned long level, in unsigned long xoff, in unsigned long yoff, in unsigned long width, in unsigned long height, in HTMLImageElement image); > +JSValue JSCanvasRenderingContext3D::texSubImage2D(ExecState* exec, const ArgList& args) > +{ > + CanvasRenderingContext3D* context = impl(); > + unsigned target = args.at(0).toInt32(exec); > + unsigned level = args.at(1).toInt32(exec); > + unsigned xoff = args.at(2).toInt32(exec); > + unsigned yoff = args.at(3).toInt32(exec); > + unsigned width = args.at(4).toInt32(exec); > + unsigned height = args.at(5).toInt32(exec); ditto > + > + ExceptionCode ec = 0; > + if (o->inherits(&JSHTMLImageElement::s_info)) { > + HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); > + context->texSubImage2D(target, level, xoff, yoff, width, height, imgElt, ec); > + } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { > + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); > + context->texSubImage2D(target, level, xoff, yoff, width, height, canvas, ec); ditto > +JSValue JSHTMLCanvasElement::getContext(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + HTMLCanvasElement* imp = static_cast<HTMLCanvasElement*>(impl()); > + const UString& contextId = args.at(0).toString(exec); > + > + JSValue result = jsUndefined(); > + > + if (contextId == "2d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(imp->getContext(contextId)))); > +#if ENABLE(3D_CANVAS) > + else if (contextId == "webkit-3d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(imp->getContext(contextId)))); > +#endif > + > + return result; > +} This makes me sad, we should probably make toJS(CanvasRenderingContext*) do the coercion there, rather than making this a custom binding. > Index: WebCore/html/CanvasByteArray.cpp > + String CanvasByteArray::toString() const > + { > + String s = "[ "; > + for (size_t i = 0; i < m_data.size(); ++i) { > + if (i != 0) > + s += ", "; > + s += String::number(m_data[i]); > + } > + > + s += " ]"; > + return s; > + } > + [DontEnum] DOMString toString(); Most other DOM objects do not have toString implementations, so this seems unusual. Its syntax also does not match the syntax standard array toString, i would suggest removing this. > + virtual void _deleteObject(Platform3DObject); why the _? > + String CanvasNumberArray::toString() const > + { > + String s = "[ "; > + for (size_t i = 0; i < m_data.size(); ++i) { > + if (i != 0) > + s += ", "; > + s += String::number(m_data[i]); > + } > + > + s += " ]"; > + return s; > + } > + [DontEnum] DOMString toString(); Same again for CanvasNumberArray. I have a feeling that these are sufficiently similar that we probably jut want template <typename T> class CanvasArray { ... }; class CanvasByteArray : CanvasArray<uint8> { ... } class CanvasNumberArray : CanvasArray<float> { ... } > + > + /* ClearBufferMask */ > + const unsigned int GL_DEPTH_BUFFER_BIT = 0x00000100; ... > + const unsigned int GL_MAX_RENDERBUFFER_SIZE = 0x84E8; I thought that we had decided that most of these constants would not be present as they are unused and unnecessary? > + void glActiveTexture (in unsigned long texture); Textures aren't identified by numeric idents so why is this here? Also why the gl prefixes this doesn't seem to match the spec > +} > + > +-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp > +{ > + CGRect frame = [self frame]; > + > + // draw the FBO into the layer > + glViewport(0, 0, frame.size.width, frame.size.height); > + glMatrixMode(GL_PROJECTION); > + glLoadIdentity(); > + glOrtho(-1, 1, -1, 1, -1, 1); > + glMatrixMode(GL_MODELVIEW); > + glLoadIdentity(); > + > + glEnable(GL_TEXTURE_2D); > + glBindTexture(GL_TEXTURE_2D, m_texture); > + > + glBegin(GL_TRIANGLE_FAN); > + glTexCoord2f(0, 0); > + glVertex2f(-1, -1); > + glTexCoord2f(1, 0); > + glVertex2f(1, -1); > + glTexCoord2f(1, 1); > + glVertex2f(1, 1); > + glTexCoord2f(0, 1); > + glVertex2f(-1, 1); > + glEnd(); > + > + glBindTexture(GL_TEXTURE_2D, 0); > + glDisable(GL_TEXTURE_2D); We draw the fbo with a triangle fan? say what? > Index: WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp > =================================================================== > --- WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp (revision 0) > +++ WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp (revision 0) > @@ -0,0 +1,1570 @@ > +/* > + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 2009 There are plenty of C-style casts in the remaining code and uses of malloc/free instead of fastMalloc/fastFree
Simon Fraser (smfr)
Comment 7 2009-08-05 12:16:49 PDT
Comment on attachment 34149 [details] Patch 3 of 4: Adding new files to the build I'd prefer that we make html/canvas and put all the new files there, and make new groupings in the Xcode project.
Simon Fraser (smfr)
Comment 8 2009-08-05 12:17:42 PDT
Comment on attachment 34151 [details] Patch 4 of 4: Connect everything up Minusing for the recalcStyle() hack that we need to figure out a better way to do.
Dimitri Glazkov (Google)
Comment 9 2009-08-05 12:26:00 PDT
Comment on attachment 34151 [details] Patch 4 of 4: Connect everything up > + [Custom,V8Custom] DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height); This can be just [Custom]
Dimitri Glazkov (Google)
Comment 10 2009-08-05 12:38:07 PDT
Comment on attachment 34146 [details] Patch 2 of 4: New Canvas 3D files Whoa, this is a chunky patch. Can we break it up into smaller pieces perhaps? > + /* > + ec = 0; > + > + if (!canvas) > + return; > + > + ensureContext; > + ImageBuffer* buffer = canvas->buffer(); > + if (!buffer) > + return; > + > + Image* img = buffer->image(); > + if (!img) > + return; > + > + ::glTexSubImage2D(target, level, xoff, yoff, width, height, GL_RGBA, GL_UNSIGNED_BYTE, img->data()->data()); > + */ > +} > + > +} > + > +#endif // ENABLE(3D_CANVAS) Probably didn't mean to leave this commented code in.
Dimitri Glazkov (Google)
Comment 11 2009-08-05 12:42:42 PDT
BTW, really exciting stuff!
Sam Weinig
Comment 12 2009-08-05 13:24:47 PDT
Comment on attachment 34149 [details] Patch 3 of 4: Adding new files to the build RE: patch 3. What about the rest of the build systems?
Simon Fraser (smfr)
Comment 13 2009-08-05 13:35:24 PDT
Comment on attachment 34146 [details] Patch 2 of 4: New Canvas 3D files My feedback: > Index: WebCore/ChangeLog > =================================================================== > --- WebCore/ChangeLog (revision 46804) > +++ WebCore/ChangeLog (working copy) > @@ -1,3 +1,407 @@ > +2009-08-05 Chris Marrin <cmarrin@apple.com> > + > + Reviewed by NOBODY (OOPS!). > + > + All of the new Canvas 3D files > + https://bugs.webkit.org/show_bug.cgi?id=28018 > + > + Patch 2 of 4. This is just the new files. They are not compiled yet You should edit down the changelog to just show each new file, and add a brief description of what each file does. You should do an initial patch that moves all existing canvas files to html/canvas, and then add your new files there. > Index: WebCore/bindings/js/JSCanvasNumberArrayCustom.cpp > =================================================================== Wrong license. This should be the 2-clause license with a date of 2009. This also applies to all the other new files. > Index: WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp > =================================================================== > +JSValue JSCanvasRenderingContext3D::glBufferData(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned target = args.at(0).toInt32(exec); > + unsigned usage = args.at(2).toInt32(exec); Should you check the number of args (here and elsewhere)? > +JSValue JSCanvasRenderingContext3D::glUniformMatrix(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned location = args.at(0).toInt32(exec); > + unsigned count = args.at(1).toInt32(exec); > + bool transpose = args.at(2).toBoolean(exec); > + > + if (!args.at(3).isObject()) > + return jsUndefined(); > + > + WebKitCSSMatrix* matrix = toWebKitCSSMatrix(args.at(3)); > + if (matrix) > + impl()->glUniformMatrix(location, transpose, matrix); > + else { > + JSObject* array = asObject(args.at(3)); > + int length = array->get(exec, Identifier(exec, "length")).toInt32(exec); > + if (length) { > + // If the first element is a WebKitCSSMatrix, assume all are Won't this crash if this assumption is false? > +JSValue JSCanvasRenderingContext3D::glUniformf(JSC::ExecState* exec, JSC::ArgList const& args) > + impl()->glUniform(location, (float) args.at(1).toNumber(exec)); Use static_cast<>, no space after ) > +JSValue JSCanvasRenderingContext3D::glDrawElements(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + unsigned mode = args.at(0).toInt32(exec); > + unsigned type = args.at(1).toInt32(exec); > + > + unsigned int count = 0; > + > + // If the third param is not an object, it is a number, which is the count. > + // In this case if there is a 4th param, it is the offset. If there is no > + // 4th param, the offset is 0 Do these assumptions needs to be checked in the code? > + if (!args.at(2).isObject()) { > + count = args.at(2).toInt32(exec); > + unsigned int offset = (args.size() > 3) ? args.at(3).toInt32(exec) : 0; > + impl()->glDrawElements(mode, count, type, (void*) offset); > + } else { > + void* passedIndices = 0; > + JSObject* array = asObject(args.at(2)); > + count = array->get(exec, Identifier(exec, "length")).toInt32(exec); > + > + if (type == GL_UNSIGNED_BYTE) { > + unsigned char* indices = (unsigned char*) malloc(count * sizeof(unsigned short)); Why is this sizeof(unsigned short)? > Index: WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp > + JSValue result = jsUndefined(); > + > + if (contextId == "2d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(imp->getContext(contextId)))); > +#if ENABLE(3D_CANVAS) > + else if (contextId == "webkit-3d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(imp->getContext(contextId)))); > +#endif > + > + return result; This would be somewhat cleaner with early returns. > Index: WebCore/html/CanvasBuffer.cpp > =================================================================== > + CanvasBuffer::CanvasBuffer(GraphicsContext3D* context) > + : CanvasObject(context) > + { > + GLuint o; > + glGenBuffers(1, &o); > + setObject(o); > + } > + > + void CanvasBuffer::_deleteObject(Platform3DObject object) > + { > + glDeleteBuffers(1, &object); > + } Should the '1' be a named constant? > Index: WebCore/html/CanvasByteArray.cpp > =================================================================== > + String CanvasByteArray::toString() const > + { > + String s = "[ "; > + for (size_t i = 0; i < m_data.size(); ++i) { > + if (i != 0) > + s += ", "; > + s += String::number(m_data[i]); > + } > + > + s += " ]"; > + return s; Lots of very inefficient string appends here. Should use append(). > Index: WebCore/html/CanvasByteArray.h > =================================================================== > + Vector<uint8_t>& data() { return m_data; } Is it ok that this is mutable? > Index: WebCore/html/CanvasFramebuffer.cpp > =================================================================== > +#include <OpenGL/OpenGL.h> It seems wrong for code outside of platform/ to be including OpenGL.h. This code needs to be platform-neutral. > Index: WebCore/html/CanvasNumberArray.cpp > =================================================================== > + String CanvasNumberArray::toString() const > + { > + String s = "[ "; > + for (size_t i = 0; i < m_data.size(); ++i) { > + if (i != 0) > + s += ", "; > + s += String::number(m_data[i]); > + } > + > + s += " ]"; Should use append here too. > Index: WebCore/html/CanvasNumberArray.h > =================================================================== > + class CanvasNumberArray : public RefCounted<CanvasNumberArray> { > + public: > + static PassRefPtr<CanvasNumberArray> create(unsigned length); > + > + Vector<float>& data() { return m_data; } > + > + unsigned length() const { return m_data.size(); } > + float item(unsigned index) { return (index >= m_data.size()) ? 0 : m_data[index]; } Should be const. > Index: WebCore/html/CanvasObject.cpp > =================================================================== > + void CanvasObject::setObject(Platform3DObject object) > + { > + deleteObject(); > + m_object = object; > + } What if m_object == object? > Index: WebCore/html/CanvasProgram.cpp > =================================================================== > +#include <OpenGL/OpenGL.h> Bad layering. > Index: WebCore/html/CanvasRenderbuffer.cpp > =================================================================== > +#include <OpenGL/OpenGL.h> Bad layering. > + CanvasRenderbuffer::CanvasRenderbuffer(GraphicsContext3D* context) > + : CanvasObject(context) > + { > + GLuint o; > + glGenRenderbuffersEXT(1, &o); > + setObject(o); > + } > + > + void CanvasRenderbuffer::_deleteObject(Platform3DObject object) > + { > + glDeleteRenderbuffersEXT(1, &object); > + } Should the '1' be a named constant? > Index: WebCore/html/CanvasRenderingContext3D.cpp > =================================================================== > +void CanvasRenderingContext3D::updateContext() > +{ > + if (m_canvas->renderBox() && m_canvas->renderBox()->hasLayer()) > + m_canvas->renderBox()->layer()->rendererContentChanged(); > +} What does "update" really mean? > +#define leave(update) { m_context.checkError(); if (update) updateContext(); } Macros should be in uppercase. Use an inline function instead? 'leave' is a really bad name. Also, boolean arguments are evil. Make 2 inline functions. > +void CanvasRenderingContext3D::glReleaseShaderCompiler () > +{ > + //::glReleaseShaderCompilerEXT(); > + leave(false); > +} Why is this commented out? > +PassRefPtr<CanvasProgram> CanvasRenderingContext3D::createProgram () Extra space after the function name (here and in many other places). > Index: WebCore/html/CanvasRenderingContext3D.h > =================================================================== > + virtual bool is3d() { return true; } Should be const. > + void glActiveTexture (unsigned long texture); > + void glAttachShader (CanvasProgram* program, CanvasShader* shader); Need to fix the spacing with all of these. In some cases the parameter names can be removed > Index: WebCore/html/CanvasRenderingContext3D.idl > =================================================================== > + readonly attribute HTMLCanvasElement canvas; > + > + void glActiveTexture (in unsigned long texture); Need to fix the spacing with all these methods declarations. > Index: WebCore/html/CanvasRenderingContext.h > =================================================================== > +namespace WebCore { > + > + class CanvasObject; > + class HTMLCanvasElement; > + > + class CanvasRenderingContext : Noncopyable { > + public: > + CanvasRenderingContext(HTMLCanvasElement*); > + virtual ~CanvasRenderingContext() { } > + > + void ref(); > + void deref(); > + > + HTMLCanvasElement* canvas() const { return m_canvas; } > + > + virtual bool is2d() { return false; } > + virtual bool is3d() { return false; } > + virtual bool is3d_1_1() { return false; } > + virtual bool is3d_fixed() { return false; } These should all be const. > Index: WebCore/html/CanvasShader.cpp > =================================================================== > +#include <OpenGL/OpenGL.h> Layering violation. > Index: WebCore/html/CanvasTexture.cpp > =================================================================== > +#include <OpenGL/OpenGL.h> Ditto. > + CanvasTexture::CanvasTexture(GraphicsContext3D* context) > + : CanvasObject(context) > + { > + GLuint o; > + glGenTextures(1, &o); > + setObject(o); > + } > + > + void CanvasTexture::_deleteObject(Platform3DObject object) > + { > + glDeleteTextures(1, &object); > + } Should the '1' be a named constant? > Index: WebCore/platform/graphics/GraphicsContext3D.cpp > =================================================================== > +void GraphicsContext3D::removeObject(CanvasObject* object) Extra space after the void. > +{ > + for (size_t i = 0; i < m_canvasObjects.size(); ++i) > + if (m_canvasObjects[i] == object) { > + m_canvasObjects.remove(i); > + return; Is this linear search going to be a performance problem? Is there a guarantee that the object will only be in the list once? Maybe use a HashSet? > Index: WebCore/platform/graphics/GraphicsContext3D.h > =================================================================== > + class GraphicsContext3D : Noncopyable { > + public: > + GraphicsContext3D(); > + virtual ~GraphicsContext3D(); > + > + PlatformGraphicsContext3D platformGraphicsContext3D() const; > + > + void checkError() const; > + > + void glActiveTexture (unsigned long texture); > + void glAttachShader (CanvasProgram* program, CanvasShader* shader); Spacing and parameter names need fixing here too. > Index: WebCore/platform/graphics/mac/Canvas3DLayer.h > =================================================================== > +-(id) initWithContext:(CGLContextObj) context texture:(GLuint) texture; No spaces after the ) here. > Index: WebCore/platform/graphics/mac/Canvas3DLayer.mm > =================================================================== > +@implementation Canvas3DLayer > + > +-(id) initWithContext:(CGLContextObj) context texture:(GLuint) texture No spaces after ) > +{ > + m_contextObj = context; > + m_texture = texture; > + [super init]; > + return self; > +} The canonical form is: if ((self = [super init])) { // do own init here } return self; > +-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp > +{ > + CGRect frame = [self frame]; > + > + // draw the FBO into the layer > + glViewport(0, 0, frame.size.width, frame.size.height); > + glMatrixMode(GL_PROJECTION); > + glLoadIdentity(); > + glOrtho(-1, 1, -1, 1, -1, 1); > + glMatrixMode(GL_MODELVIEW); > + glLoadIdentity(); > + > + glEnable(GL_TEXTURE_2D); > + glBindTexture(GL_TEXTURE_2D, m_texture); > + > + glBegin(GL_TRIANGLE_FAN); > + glTexCoord2f(0, 0); > + glVertex2f(-1, -1); > + glTexCoord2f(1, 0); > + glVertex2f(1, -1); > + glTexCoord2f(1, 1); > + glVertex2f(1, 1); > + glTexCoord2f(0, 1); > + glVertex2f(-1, 1); > + glEnd(); You have tabs here. > + glBindTexture(GL_TEXTURE_2D, 0); > + glDisable(GL_TEXTURE_2D); > + > + // Call super to finalize the drawing. By default all it does is call glFlush(). > + [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp]; More tabs. > Index: WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp > =================================================================== > +void GraphicsContext3D::checkError() const > +{ > + GLenum error = ::glGetError(); > + if (error != GL_NO_ERROR) > + fprintf(stderr, "*** GL error %d\n", error); > +} Shouldn't these propagate back to Console? > +#define ensureContext _ensureContext(m_contextObj) Make the macro uppercase, or, preferably, just use an inline method. WebKit macros are normally written to look like functions, i.e. with parens. > +void GraphicsContext3D::glAttachShader (CanvasProgram* program, CanvasShader* shader) Spacing needs cleanup. > +void GraphicsContext3D::glClearColor(double r, double g, double b, double a) > +{ > + ensureContext; > + if (isnan(r)) > + r = 0; > + if (isnan(g)) > + g = 0; > + if (isnan(b)) > + b = 0; > + if (isnan(a)) > + a = 1; It seems like NANs should never get down to GraphicsContext3D; the upper layers should do this conversion. > + ::glClearColor((float) r, (float) g, (float) b, (float) a); static_cast please. > +void GraphicsContext3D::glFinish () > +{ > + ensureContext; > + ::glFinish(); > +} > + > + Extra blank line. > +void GraphicsContext3D::glReleaseShaderCompiler () > +{ > + ensureContext; > + //::glReleaseShaderCompilerEXT(); Why is this commented out? If it's a feature that is not yet implemented, then maybe use an #ifdef? > +void GraphicsContext3D::glUniformMatrix(long location, long count, bool transpose, CanvasNumberArray*array) Space after the * > + int n = array->data().size() / count; > + if (n < 2) > + return; > + > + if (n > 4) > + n = 4; Should these be asserting? > +void GraphicsContext3D::glUniformMatrix(long location, bool transpose, const Vector<WebKitCSSMatrix*>& array) > +{ > + int count = array.size(); > + float* floats = (float*) malloc(count * 16 * sizeof(float)); > + > + for (int i = 0; i < count; ++i) { > + floats[i*16+ 0] = (float) array[i]->m11(); static_cast > +void GraphicsContext3D::glUniformMatrix(long location, bool transpose, const WebKitCSSMatrix* matrix) > +{ > + floats[ 0] = (float) matrix->m11(); Ditto > +void GraphicsContext3D::glViewport(long x, long y, unsigned long width, unsigned long height) > +{ > + ensureContext; > + if (isnan(x)) > + x = 0; > + if (isnan(y)) > + y = 0; > + if (isnan(width)) > + width = 100; > + if (isnan(height)) > + height = 100; Again, seems like NANs should be filtered out higher up. Arbitrary values (like 100) should not live in platform code. > +// Assumes the texture you want to go into is bound > +static void imageToTexture(Image* image, unsigned target, unsigned level) > +{ > + if (!image) > + return; > + > + CGImageRef textureImage = image->getCGImageRef(); > + if (!textureImage) > + return; > + > + size_t textureWidth = CGImageGetWidth(textureImage); > + size_t textureHeight = CGImageGetHeight(textureImage); > + > + GLubyte* textureData = (GLubyte*) malloc(textureWidth*textureHeight*4); > + CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth, textureHeight, 8, textureWidth*4, > + CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast); > + Spaces around the * please.
Simon Fraser (smfr)
Comment 14 2009-08-05 14:05:00 PDT
Comment on attachment 34151 [details] Patch 4 of 4: Connect everything up > Index: WebCore/ChangeLog > =================================================================== > + Connect everything up > + https://bugs.webkit.org/show_bug.cgi?id=28018 > + > + Changes to CanvasElement, GraphicsLayer, the style logic and > + rendering logic for Canvas 3D. I'd like to see more detail here. At least annotate the change list to describe the substantive changes to each file. > Index: WebCore/bindings/js/JSDocumentCustom.cpp > =================================================================== > +JSValue JSDocument::getCSSCanvasContext(JSC::ExecState* exec, JSC::ArgList const& args) Why did you have to add this function? > +{ > + const UString& contextId = args.at(0).toString(exec); > + const UString& name = args.at(1).toString(exec); > + int width = args.at(2).toInt32(exec); > + int height = args.at(3).toInt32(exec); Check the argument count? > + if (contextId == "2d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(impl()->getCSSCanvasContext(contextId, name, width, height)))); > +#if ENABLE(3D_CANVAS) > + else if (contextId == "webkit-3d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(impl()->getCSSCanvasContext(contextId, name, width, height)))); > +#endif > + > + return result; Early returns would be clearer. > Index: WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp > =================================================================== > + * Copyright (C) 2007 Apple Inc. All rights reserved. Date needs fixing. > +JSValue JSHTMLCanvasElement::getContext(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + HTMLCanvasElement* imp = static_cast<HTMLCanvasElement*>(impl()); > + const UString& contextId = args.at(0).toString(exec); > + > + JSValue result = jsUndefined(); > + > + if (contextId == "2d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(imp->getContext(contextId)))); > +#if ENABLE(3D_CANVAS) > + else if (contextId == "webkit-3d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(imp->getContext(contextId)))); > +#endif > + > + return result; Again, prefer early returns. > Index: WebCore/dom/Document.h > =================================================================== > + CanvasRenderingContext* getCSSCanvasContext(const String& type, const String& name, int width, int height); Wow, so, after your changes, can I reference a canvas3D in CSS as background image? > Index: WebCore/dom/Element.cpp > =================================================================== > --- WebCore/dom/Element.cpp (revision 46800) > +++ WebCore/dom/Element.cpp (working copy) > @@ -821,6 +821,11 @@ void Element::recalcStyle(StyleChange ch > if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) { > RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this); > StyleChange ch = diff(currentStyle, newStyle.get()); > + > + // We need to force a set style if we have a 3D canvas without a compositing layer > + if (renderer() && renderer()->isCanvas3D() && !renderer()->hasLayer()) > + ch = Force; > + We need to do this differently. There's no guarantee that recalcStyle will happen after you request a canvas-3d context. We should talk to hyatt about how best to make a layer for a canvas as soon as the 3d context is requested. > Index: WebCore/html/CanvasRenderingContext2D.h > =================================================================== > + virtual bool is2d() { return true; } Should be const > Index: WebCore/html/HTMLCanvasElement.cpp > =================================================================== > CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) > { > if (type == "2d") { > - if (!m_2DContext) > - m_2DContext.set(new CanvasRenderingContext2D(this)); > - return m_2DContext.get(); > + if (m_context && !m_context->is2d()) > + m_context.clear(); > + if (!m_context) > + m_context.set(new CanvasRenderingContext2D(this)); > } > - return 0; > +#if ENABLE(3D_CANVAS) > + else if (type == "webkit-3d") { > + if (m_context && !m_context->is3d()) > + m_context.clear(); > + if (!m_context) { > + m_context.set(new CanvasRenderingContext3D(this)); > + setNeedsStyleRecalc(); > + } > + } > +#endif > + else if (m_context.get()) > + m_context.clear(); > + > + return m_context.get(); I think this needs some comments explaining the behavior when the author requests both 2d and 3d rendering contexts on the same canvas. > +bool HTMLCanvasElement::is3D() const > +{ > + CanvasRenderingContext* ctx = m_context.get(); > + return ctx && !ctx->is2d(); > +} Is the entire canvas really in 3d mode, or can I mix and match? > +PlatformGraphicsContext3D HTMLCanvasElement::context3D() const > +{ > + if (m_context && m_context->is3d()) > + return static_cast<CanvasRenderingContext3D*>(m_context.get())->context3D(); > + else > + return 0; No 'else' after 'return'. > +Platform3DObject HTMLCanvasElement::texture3D() const > +{ > + if (m_context && m_context->is3d()) > + return static_cast<CanvasRenderingContext3D*>(m_context.get())->texture3D(); > + else > + return 0; Ditto. > Index: WebCore/page/DOMWindow.idl > =================================================================== > --- WebCore/page/DOMWindow.idl (revision 46800) > +++ WebCore/page/DOMWindow.idl (working copy) > @@ -406,6 +406,7 @@ module window { > attribute [CustomGetter] HTMLOptionElementConstructor Option; // Usable with new operator > > attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D; > + attribute [Conditional=3D_CANVAS] CanvasRenderingContext3DConstructor CanvasRenderingContext3D; > attribute TextMetricsConstructor TextMetrics; This change is going to affect layout tests I think. > Index: WebCore/platform/graphics/GraphicsLayer.h > =================================================================== > +#if PLATFORM(MAC) > +//#include <OpenGL/OpenGL.h> > +#endif Do you need this? > +#if ENABLE(3D_CANVAS) > + virtual void setContentsToCanvas3D(PlatformLayer*) { } > + virtual void redrawCanvas3D() { } Do you really mean redraw, or is it something else? > +#if ENABLE(3D_CANVAS) > + void setHas3DLayer(bool has3DLayer, PlatformGraphicsContext3D context, Platform3DObject texture); > +#endif I'm not sure why you need both this and setContentsToCanvas3D()? Also, I think the last two params should have default arguments so you can call setHas3DLayer(false). > +#if ENABLE(3D_CANVAS) > + bool m_3d : 1; I don't like the name of this member variable; it's really not clear what it means. Also, does it belong in the base class? Using GraphicsLayer for a canvas-3d might be a Mac-specific thing. > Index: WebCore/platform/graphics/mac/GraphicsLayerCA.mm > =================================================================== > +#if ENABLE(3D_CANVAS) > +void GraphicsLayerCA::setContentsToCanvas3D(PlatformLayer* layer) > +{ > + > + > + Lots of whitespace there. > +#if ENABLE(3D_CANVAS) > +void GraphicsLayer::setHas3DLayer(bool has3DLayer, PlatformGraphicsContext3D context, Platform3DObject texture) > +{ > + BEGIN_BLOCK_OBJC_EXCEPTIONS > + > + if (has3DLayer && !m_3d) { > + // create the inner 3d layer > + PlatformLayer* layer = [[Canvas3DLayer alloc] initWithContext:(CGLContextObj) context texture: (GLuint) texture]; No spaces after the ) > + [layer setName:@"3D Layer"]; Names should only be set in debug. > +void GraphicsLayerCA::redrawCanvas3D() > +{ > + if (m_3d) > + [m_contentsLayer.get() setNeedsDisplay]; > +} This needs to go through the batching mechanism. > Index: WebCore/rendering/RenderBoxModelObject.h > =================================================================== > --- WebCore/rendering/RenderBoxModelObject.h (revision 46800) > +++ WebCore/rendering/RenderBoxModelObject.h (working copy) > @@ -59,7 +59,14 @@ public: > > bool hasSelfPaintingLayer() const; > RenderLayer* layer() const { return m_layer; } > - virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); } > + virtual bool requiresLayer() const > + { > + return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection() > +#if USE(ACCELERATED_COMPOSITING) > + || isCanvas3D() > +#endif FYI, you've added a virtual method call to this somewhat hot method; all the other tests are inlined. > Index: WebCore/rendering/RenderLayerBacking.cpp > =================================================================== > + else if (renderer()->isCanvas3D()) { > + m_hasDirectlyCompositedContent = true; > + HTMLCanvasElement* canvas = reinterpret_cast<HTMLCanvasElement*>(renderer()->node()); > + if (canvas && canvas->context3D()) { > + m_graphicsLayer->setHas3DLayer(true, canvas->context3D(), canvas->texture3D()); > + m_graphicsLayer->setDrawsContent(true); I'm not sure you need the setDrawsContent(true) since you don't want normal backing store for the layer.
Kenneth Russell
Comment 15 2009-08-05 14:32:16 PDT
Glad to see this work landing. The current WebGL spec uses CanvasRenderingContextGL as the JavaScript interface name. To avoid future file renamings, which are problematic with SVN, should CanvasRenderingContext3D and GraphicsContext3D be renamed to CanvasRenderingContextGL and GraphicsContextGL before initial checkin? Also, the UUIDs for many of the new IDL files are duplicates of those from CanvasRenderingContext2D. I don't know whether the COM bindings are still used, but these bogus UUIDs should either be removed or replaced with real ones generated by a tool like http://www.famkruithof.net/uuid/uuidgen .
Mark Rowe (bdash)
Comment 16 2009-08-05 16:02:41 PDT
(In reply to comment #15) > Glad to see this work landing. > > The current WebGL spec uses CanvasRenderingContextGL as the JavaScript > interface name. To avoid future file renamings, which are problematic with SVN, > should CanvasRenderingContext3D and GraphicsContext3D be renamed to > CanvasRenderingContextGL and GraphicsContextGL before initial checkin? File renaming isn't a problem in SVN. We do it relatively frequently.
Kenneth Russell
Comment 17 2009-08-05 16:24:36 PDT
(In reply to comment #16) > (In reply to comment #15) > > Glad to see this work landing. > > > > The current WebGL spec uses CanvasRenderingContextGL as the JavaScript > > interface name. To avoid future file renamings, which are problematic with SVN, > > should CanvasRenderingContext3D and GraphicsContext3D be renamed to > > CanvasRenderingContextGL and GraphicsContextGL before initial checkin? > > File renaming isn't a problem in SVN. We do it relatively frequently. Doesn't it require an intermediate checkin of the renamed file before changing the contents under the new name? That was my experience with Java sources and it was a real pain because the build would be broken for a period of time.
Chris Marrin
Comment 18 2009-08-06 08:13:24 PDT
Landed the first patch (Add ENABLE_3D_CANVAS flag to the build) Sending WebCore/ChangeLog Sending WebCore/Configurations/FeatureDefines.xcconfig Sending WebKit/mac/ChangeLog Sending WebKit/mac/Configurations/FeatureDefines.xcconfig Sending WebKitTools/ChangeLog Sending WebKitTools/Scripts/build-webkit Transmitting file data ...... Committed revision 46844.
Chris Marrin
Comment 19 2009-08-21 12:11:48 PDT
Created attachment 38385 [details] Patch for new Canvas3D files This patch incorporates comments from Simon and Oliver. Note that this is not all the new files. I've left a few of the JS binding files out since they will require more rework, and this gives a more manageable set of files to review.
Simon Fraser (smfr)
Comment 20 2009-08-21 12:16:22 PDT
Comment on attachment 38385 [details] Patch for new Canvas3D files The new files should be in html/canvas.
Simon Fraser (smfr)
Comment 21 2009-08-21 12:20:20 PDT
Comment on attachment 38385 [details] Patch for new Canvas3D files New files should use the 2-clause license, e.g. like WebKitCSSKeyframeRule
Oliver Hunt
Comment 22 2009-08-21 15:18:55 PDT
Comment on attachment 38385 [details] Patch for new Canvas3D files Files are in the wrong directory :D Minor style gripe: CanvasObject::CanvasObject -> the member constructors should be indented GraphicsContext3D::checkError -> I'd prefer notImplemented() in place of what's currently there GraphicsContext3D::reshape -> ASSERT(0) should be ASSERT_NOT_REACHED() or notImplemented() GraphicsContext3D::texSubImage2D -> We don't check in commented out code Other than these gripes, r=me -- when landed file a bug on updating to current API
Chris Marrin
Comment 23 2009-08-21 15:45:38 PDT
Sending WebCore/ChangeLog Adding WebCore/bindings/js/JSCanvasNumberArrayCustom.cpp Adding WebCore/html/canvas/CanvasObject.cpp Adding WebCore/html/canvas/CanvasObject.h Adding WebCore/html/canvas/CanvasRenderingContext.cpp Adding WebCore/html/canvas/CanvasRenderingContext.h Adding WebCore/html/canvas/CanvasRenderingContext.idl Adding WebCore/html/canvas/CanvasRenderingContext3D.cpp Adding WebCore/html/canvas/CanvasRenderingContext3D.h Adding WebCore/html/canvas/CanvasRenderingContext3D.idl Adding WebCore/platform/graphics/GraphicsContext3D.cpp Adding WebCore/platform/graphics/GraphicsContext3D.h Adding WebCore/platform/graphics/mac/Canvas3DLayer.h Adding WebCore/platform/graphics/mac/Canvas3DLayer.mm Adding WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp Transmitting file data ............... Committed revision 47645.
Chris Marrin
Comment 24 2009-08-21 15:46:32 PDT
Comment on attachment 34145 [details] Patch 1 of 4: Add ENABLE_3D_CANVAS flag to the build Landed this patch
Chris Marrin
Comment 25 2009-08-21 15:47:12 PDT
Comment on attachment 38385 [details] Patch for new Canvas3D files Landed this patch
Chris Marrin
Comment 26 2009-08-21 17:52:18 PDT
Created attachment 38426 [details] Patch with new GL Object files
Simon Fraser (smfr)
Comment 27 2009-08-21 18:06:23 PDT
Comment on attachment 38426 [details] Patch with new GL Object files > diff --git a/WebCore/html/canvas/CanvasObject.h b/WebCore/html/canvas/CanvasObject.h > index 55cc525..d89264a 100644 > --- a/WebCore/html/canvas/CanvasObject.h > +++ b/WebCore/html/canvas/CanvasObject.h > @@ -52,6 +52,8 @@ namespace WebCore { > protected: > CanvasObject(GraphicsContext3D*); > virtual void _deleteObject(Platform3DObject) = 0; > + > + GraphicsContext3D* context() { return m_context; } Should be |const| The rest looks good.
Chris Marrin
Comment 28 2009-08-22 06:12:09 PDT
Sending WebCore/ChangeLog Adding WebCore/html/canvas/CanvasBuffer.cpp Adding WebCore/html/canvas/CanvasBuffer.h Adding WebCore/html/canvas/CanvasBuffer.idl Adding WebCore/html/canvas/CanvasFramebuffer.cpp Adding WebCore/html/canvas/CanvasFramebuffer.h Adding WebCore/html/canvas/CanvasFramebuffer.idl Sending WebCore/html/canvas/CanvasObject.h Adding WebCore/html/canvas/CanvasProgram.cpp Adding WebCore/html/canvas/CanvasProgram.h Adding WebCore/html/canvas/CanvasProgram.idl Adding WebCore/html/canvas/CanvasRenderbuffer.cpp Adding WebCore/html/canvas/CanvasRenderbuffer.h Adding WebCore/html/canvas/CanvasRenderbuffer.idl Sending WebCore/html/canvas/CanvasRenderingContext3D.cpp Sending WebCore/html/canvas/CanvasRenderingContext3D.h Adding WebCore/html/canvas/CanvasShader.cpp Adding WebCore/html/canvas/CanvasShader.h Adding WebCore/html/canvas/CanvasShader.idl Adding WebCore/html/canvas/CanvasTexture.cpp Adding WebCore/html/canvas/CanvasTexture.h Adding WebCore/html/canvas/CanvasTexture.idl Deleting WebCore/platform/graphics/GraphicsContext3D.cpp Sending WebCore/platform/graphics/GraphicsContext3D.h Sending WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp Transmitting file data ........................ Committed revision 47670.
Chris Marrin
Comment 29 2009-08-22 06:12:42 PDT
Comment on attachment 38426 [details] Patch with new GL Object files Patch was landed
Dimitri Glazkov (Google)
Comment 30 2009-08-22 08:19:11 PDT
Build fix landed as http://trac.webkit.org/changeset/47671. http://trac.webkit.org/changeset/47669 started using CanvasRenderingContext and it wasn't yet hooked up to build. It didn't fix everything, because CanvasRenderingContext is also typedef'd to CanvasRenderingContext2D in HTMLCanvasElement.h. Fixing more ...
Sam Weinig
Comment 31 2009-08-22 08:59:31 PDT
Any reason the new files aren't in any of the project files?
Chris Marrin
Comment 32 2009-08-22 08:59:31 PDT
Ack! Sorry. I was trying to commit using git svn and I obviously botched it. Those files should never have been committed. I will fix them right now
Chris Marrin
Comment 33 2009-08-23 16:32:56 PDT
Created attachment 38460 [details] Patch with remaining new files
Simon Fraser (smfr)
Comment 34 2009-08-23 21:36:26 PDT
Comment on attachment 38460 [details] Patch with remaining new files > Index: WebCore/ChangeLog > =================================================================== > + * bindings/js/JSHTMLCanvasElementCustom.cpp: Added Canvas3D method behind an ifdef > + * html/CanvasByteArray.cpp: Added. Efficient array of bytes for passing to GL functions > + * html/CanvasByteArray.h: Added. > + * html/CanvasByteArray.idl: Added. > + * html/CanvasNumberArray.cpp: Added. Efficient array of 32 bit floats for passing to GL functions > + * html/CanvasNumberArray.h: Added. > + * html/CanvasNumberArray.idl: Added. New files are going to go in html/canvas, right? > Index: WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp > =================================================================== > +#if ENABLE(3D_CANVAS) > +JSValue JSHTMLCanvasElement::getContext(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + HTMLCanvasElement* imp = static_cast<HTMLCanvasElement*>(impl()); > + const UString& contextId = args.at(0).toString(exec); > + > + if (contextId == "2d") > + return toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(imp->getContext(contextId)))); > + else if (contextId == "webkit-3d") > + return toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(imp->getContext(contextId)))); No 'else' after 'return'. > Index: WebCore/html/CanvasByteArray.cpp > =================================================================== > + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of > + * its contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. Should be 2-clause license. Are the dates right? Same for other files. > Index: WebCore/html/CanvasNumberArray.h > =================================================================== > +namespace WebCore { > + > + class String; > + > + class CanvasNumberArray : public RefCounted<CanvasNumberArray> { > + public: > + static PassRefPtr<CanvasNumberArray> create(unsigned length); > + > + Vector<float>& data() { return m_data; } > + > + unsigned length() const { return m_data.size(); } > + float item(unsigned index) { return (index >= m_data.size()) ? 0 : m_data[index]; } This should be 'const'. Do you want a const data() accessor too? Fix the above, and r=me
Chris Marrin
Comment 35 2009-08-24 06:39:44 PDT
Sending WebCore/ChangeLog Sending WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp Adding WebCore/html/canvas/CanvasByteArray.cpp Adding WebCore/html/canvas/CanvasByteArray.h Adding WebCore/html/canvas/CanvasByteArray.idl Adding WebCore/html/canvas/CanvasNumberArray.cpp Adding WebCore/html/canvas/CanvasNumberArray.h Adding WebCore/html/canvas/CanvasNumberArray.idl Transmitting file data ........ Committed revision 47708.
Chris Marrin
Comment 36 2009-08-24 06:40:25 PDT
Comment on attachment 38460 [details] Patch with remaining new files Landed this patch
Chris Marrin
Comment 37 2009-08-24 09:47:43 PDT
Created attachment 38483 [details] Patch to add Canvas3D files to build Note that the 3D-Canvas flag is off by default, so most of this code is not yet used. But the addition of CanvasRenderingContext as the base class for CanvasRenderingContext2D is in all builds
Simon Fraser (smfr)
Comment 38 2009-08-24 11:20:19 PDT
Comment on attachment 38483 [details] Patch to add Canvas3D files to build > Index: WebCore/bindings/js/JSDocumentCustom.cpp > =================================================================== > + if (contextId == "2d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(impl()->getCSSCanvasContext(contextId, name, width, height)))); > +#if ENABLE(3D_CANVAS) > + else if (contextId == "webkit-3d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(impl()->getCSSCanvasContext(contextId, name, width, height)))); > +#endif > + > + return result; No 'else' after 'return'. > Index: WebCore/html/HTMLCanvasElement.cpp > =================================================================== > +#if ENABLE(3D_CANVAS) > +bool HTMLCanvasElement::is3D() const > +{ > + CanvasRenderingContext* ctx = m_context.get(); > + return ctx && !ctx->is2d(); Why not ctx && ctx->is3d() ? > +PlatformGraphicsContext3D HTMLCanvasElement::context3D() const > +{ > + if (m_context && m_context->is3d()) > + return static_cast<CanvasRenderingContext3D*>(m_context.get())->context3D(); > + else > + return 0; No 'else' after 'return'. > +Platform3DObject HTMLCanvasElement::texture3D() const > +{ > + if (m_context && m_context->is3d()) > + return static_cast<CanvasRenderingContext3D*>(m_context.get())->texture3D(); > + else > + return 0; No 'else' after 'return'. > Index: WebCore/html/HTMLCanvasElement.h > =================================================================== > - CanvasRenderingContext2D* renderingContext2D() { return m_2DContext.get(); } > + CanvasRenderingContext* renderingContext() { return m_context.get(); } Method should be 'const'.
Oliver Hunt
Comment 39 2009-08-24 11:47:21 PDT
Comment on attachment 38483 [details] Patch to add Canvas3D files to build > +JSValue JSDocument::getCSSCanvasContext(JSC::ExecState* exec, JSC::ArgList const& args) > +{ > + const UString& contextId = args.at(0).toString(exec); > + const UString& name = args.at(1).toString(exec); > + int width = args.at(2).toInt32(exec); > + int height = args.at(3).toInt32(exec); > + > + JSValue result = jsUndefined(); > + > + if (contextId == "2d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext2D*>(impl()->getCSSCanvasContext(contextId, name, width, height)))); > +#if ENABLE(3D_CANVAS) > + else if (contextId == "webkit-3d") > + result = toJS(exec, WTF::getPtr(reinterpret_cast<CanvasRenderingContext3D*>(impl()->getCSSCanvasContext(contextId, name, width, height)))); > +#endif > + > + return result; > +} rather than result =... i'd prefer return toJS ... return toJS ... return jsUndefined(); > CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) > { > if (type == "2d") { > - if (!m_2DContext) > - m_2DContext.set(new CanvasRenderingContext2D(this)); > - return m_2DContext.get(); > + if (m_context && !m_context->is2d()) > + m_context.clear(); > + if (!m_context) > + m_context.set(new CanvasRenderingContext2D(this)); > } > - return 0; > +#if ENABLE(3D_CANVAS) > + else if (type == "webkit-3d") { > + if (m_context && !m_context->is3d()) > + m_context.clear(); > + if (!m_context) { > + m_context.set(new CanvasRenderingContext3D(this)); > + setNeedsStyleRecalc(); > + } > + } > +#endif > + else if (m_context.get()) > + m_context.clear(); > + > + return m_context.get(); What happens when you ask for an invalid context type (before this patch) is you get undefined back, but the context remains live. After this patch the context is destroyed. My reading of the spec says that this is incorrect. A minor fix is to change > + else if (m_context.get()) > + m_context.clear(); to > + else > + return 0; I feel better way would be to make the if (2d) and if (3d) paths return directly, then you can just drop all the else blocks, and return 0 at the end > +PlatformGraphicsContext3D HTMLCanvasElement::context3D() const > +{ > + if (m_context && m_context->is3d()) > + return static_cast<CanvasRenderingContext3D*>(m_context.get())->context3D(); > + else > + return 0; drop the else and return 0 directly. > +} > + > +Platform3DObject HTMLCanvasElement::texture3D() const > +{ > + if (m_context && m_context->is3d()) > + return static_cast<CanvasRenderingContext3D*>(m_context.get())->texture3D(); > + else > + return 0; > +} ditto I think simon had a few comments so if you address those as well, r=me
Chris Marrin
Comment 40 2009-08-25 09:29:45 PDT
Created attachment 38551 [details] Replacement patch to add Canvas3D files to build
Chris Marrin
Comment 41 2009-08-25 10:15:03 PDT
Created attachment 38555 [details] One more replacement patch to add Canvas3D files to build
Chris Marrin
Comment 42 2009-08-25 10:16:08 PDT
Comment on attachment 38555 [details] One more replacement patch to add Canvas3D files to build This file adds project files for all the builds, to add CanvasRenderingContext
Simon Fraser (smfr)
Comment 43 2009-08-25 10:30:03 PDT
Comment on attachment 38555 [details] One more replacement patch to add Canvas3D files to build > CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type) > { > + // A Canvas can either be "2D" or "3D" never both. If you request a 2D canvas and the existing > + // context is already 2D, just return that. If the existing context is 3D, then destroy it > + // before creating a new 2D context. Vice versa when requesting a 3D canvas. Requesting a > + // context with any other type string will destroy any existing context. > if (type == "2d") { > - if (!m_2DContext) > - m_2DContext.set(new CanvasRenderingContext2D(this)); > - return m_2DContext.get(); > + if (m_context && !m_context->is2d()) > + m_context.clear(); > + if (!m_context) > + m_context.set(new CanvasRenderingContext2D(this)); > } > - return 0; > +#if ENABLE(3D_CANVAS) > + else if (type == "webkit-3d") { > + if (m_context && !m_context->is3d()) > + m_context.clear(); > + if (!m_context) { > + m_context.set(new CanvasRenderingContext3D(this)); > + setNeedsStyleRecalc(); > + } > + } > +#endif This logic seems wrong. I don't grok the if (!m_context) tests. > @@ -192,8 +212,8 @@ void HTMLCanvasElement::reset() > bool hadImageBuffer = m_createdImageBuffer; > m_createdImageBuffer = false; > m_imageBuffer.clear(); > - if (m_2DContext) > - m_2DContext->reset(); > + if (m_context && m_context->is2d()) > + static_cast<CanvasRenderingContext2D*>(m_context.get())->reset(); What about the 3d context? Is there a notion of 'reset' for 3d? > - CanvasRenderingContext2D* renderingContext2D() { return m_2DContext.get(); } > + CanvasRenderingContext* renderingContext() { return m_context.get(); } Still missing the 'const'. > Index: WebCore/html/canvas/CanvasRenderingContext.idl > =================================================================== > --- WebCore/html/canvas/CanvasRenderingContext.idl (revision 47748) > +++ WebCore/html/canvas/CanvasRenderingContext.idl (working copy) > @@ -27,12 +27,12 @@ module html { > > interface [ > GenerateConstructor, > + CustomToJS, > InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443, > ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54 > ] CanvasRenderingContext { > > readonly attribute HTMLCanvasElement canvas; > - readonly attribute DOMString type; Why did this go away?
Simon Fraser (smfr)
Comment 44 2009-08-25 11:41:50 PDT
Comment on attachment 38555 [details] One more replacement patch to add Canvas3D files to build r=me with comments addressed
Chris Marrin
Comment 45 2009-08-25 11:46:34 PDT
Sending JavaScriptCore/ChangeLog Sending JavaScriptCore/JavaScriptCore.exp Sending LayoutTests/ChangeLog Sending LayoutTests/fast/dom/prototype-inheritance-2-expected.txt Sending WebCore/ChangeLog Sending WebCore/DerivedSources.cpp Sending WebCore/DerivedSources.make Sending WebCore/GNUmakefile.am Sending WebCore/WebCore.gypi Sending WebCore/WebCore.pro Sending WebCore/WebCore.vcproj/WebCore.vcproj Sending WebCore/WebCore.xcodeproj/project.pbxproj Sending WebCore/WebCoreSources.bkl Sending WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp Sending WebCore/bindings/js/JSDOMBinding.cpp Sending WebCore/bindings/js/JSDocumentCustom.cpp Sending WebCore/bindings/js/JSHTMLCanvasElementCustom.cpp Sending WebCore/dom/Document.cpp Sending WebCore/dom/Document.h Sending WebCore/html/HTMLCanvasElement.cpp Sending WebCore/html/HTMLCanvasElement.h Sending WebCore/html/canvas/CanvasObject.cpp Sending WebCore/html/canvas/CanvasRenderingContext.idl Sending WebCore/html/canvas/CanvasRenderingContext2D.cpp Sending WebCore/html/canvas/CanvasRenderingContext2D.h Sending WebCore/html/canvas/CanvasRenderingContext2D.idl Sending WebCore/html/canvas/CanvasRenderingContext3D.idl Transmitting file data ........................... Committed revision 47752.
Chris Marrin
Comment 46 2009-08-25 11:47:01 PDT
Comment on attachment 38555 [details] One more replacement patch to add Canvas3D files to build Landed this patch
Chris Marrin
Comment 47 2009-08-25 16:49:46 PDT
Created attachment 38576 [details] Patch with Platform specific rendering changes for Canvas3D
Chris Marrin
Comment 48 2009-08-27 06:39:39 PDT
Created attachment 38667 [details] Final patch for Canvas3D work
Simon Fraser (smfr)
Comment 49 2009-08-27 08:43:56 PDT
Comment on attachment 38667 [details] Final patch for Canvas3D work > Index: WebCore/ChangeLog > =================================================================== > + Reviewed by NOBODY (OOPS!). > + > + Final patch for Canvas 3D support > + https://bugs.webkit.org/show_bug.cgi?id=28018 > + > + This hooks everything up and provides a working implementation of > + Canvas 3D. You need to explain a few things here, like the style recalc hack, the fact that a 3d canvas needs a RenderLayer and a compositing layer, and why. The whole point of changelogs (and the commit message) is to explain why the changes were made so that someone can come back later and figure out why you made the changes you did. Often that person is the committer! > Index: WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp > =================================================================== > - count = args.at(2).toInt32(exec); > + unsigned int count = args.at(2).toInt32(exec); You are shadowing a variable at function scope here. A different name is probably better. > Index: WebCore/html/HTMLCanvasElement.cpp > =================================================================== > if (!m_context) { > m_context.set(new CanvasRenderingContext3D(this)); > - setNeedsStyleRecalc(); > + setNeedsStyleRecalc(SyntheticStyleChange); You need a comment here explaining why you call setNeedsStyleRecalc(). > Index: WebCore/platform/graphics/GraphicsContext3D.h > =================================================================== > > typedef void* PlatformGraphicsContext3D; > +#define NO_PLATFORM_GRAPHICS_CONTEXT_3D 0 > typedef GLuint Platform3DObject; > +#define NO_PLATFORM_3D_OBJECT 0 > #else > typedef void* PlatformGraphicsContext3D; > +#define NO_PLATFORM_GRAPHICS_CONTEXT_3D 0 > typedef int Platform3DObject; > +#define NO_PLATFORM_3D_OBJECT 0 > #endif It seems that NO_PLATFORM_GRAPHICS_CONTEXT_3D and NO_PLATFORM_3D_OBJECT should be constants, rather than #defines, like: typedef void* PlatformGraphicsContext3D; const PlatformGraphicsContext3D NullPlatformGraphicsContext3D = 0; typedef GLuint Platform3DObject; const Platform3DObject NullPlatform3DObject = 0; > Index: WebCore/platform/graphics/GraphicsLayer.h > =================================================================== > typedef void* PlatformLayer; > -typedef void* NativeLayer; > +typedef int NativeLayer; Why this change? It's not 64-bit friendly. > +#if ENABLE(3D_CANVAS) > + virtual void setContentsTo3DCanvas(PlatformGraphicsContext3D, Platform3DObject) { } For setContentsTo3DCanvas(), the method names needs to match the arguments. You're not passing in a canvas 3d, so perhaps it should be setContentsToTexture() or something. Can the argument just be a GraphicsContext3D? > + virtual void redraw3DCanvas() { } I don't like "redraw". What does it really mean? "recomposite"? Can setNeedsDisplay() do the same job? > +#if ENABLE(3D_CANVAS) > + void setHas3DLayer(bool has3DLayer, PlatformGraphicsContext3D context = NO_PLATFORM_GRAPHICS_CONTEXT_3D, Platform3DObject texture = NO_PLATFORM_3D_OBJECT); > +#endif Why do you need both this and the above method? > Index: WebCore/platform/graphics/mac/GraphicsLayerCA.h > =================================================================== > +#if ENABLE(3D_CANVAS) > + void updateContents3DCanvas(); > +#endif Maybe updateContentsTexture()? > +#if ENABLE(3D_CANVAS) > + PlatformGraphicsContext3D m_3DContext; > + Platform3DObject m_3DTexture; > +#endif What's the ownership model for these members? Who is responsible for freeing the associated resources? > Index: WebCore/platform/graphics/mac/GraphicsLayerCA.mm > =================================================================== > +#if ENABLE(3D_CANVAS) > +void GraphicsLayerCA::setContentsTo3DCanvas(PlatformGraphicsContext3D context, Platform3DObject texture) > +{ > + if (context == m_3DContext && texture == m_3DTexture) > + return; > + > + m_3DContext = context; > + m_3DTexture = texture; > + > + noteLayerPropertyChanged(ChildrenChanged); > + > + BEGIN_BLOCK_OBJC_EXCEPTIONS > + > + if (context != NO_PLATFORM_GRAPHICS_CONTEXT_3D && texture != NO_PLATFORM_3D_OBJECT) { > + // create the inner 3d layer > + m_contentsLayer = [[Canvas3DLayer alloc] initWithContext:(CGLContextObj) context texture: (GLuint) texture]; This is leaking the Canvas3DLayer. you need to use AdoptNS. No spaces after the, and use static_cast<>. > +#if ENABLE(3D_CANVAS) > +void GraphicsLayerCA::redraw3DCanvas() > +{ > + if (m_contentsLayerPurpose == ContentsLayerFor3DCanvas) > + [m_contentsLayer.get() setNeedsDisplay]; > +} > +#endif Aha, it is just setNeedsDisplay! > Index: WebCore/rendering/RenderHTMLCanvas.cpp > =================================================================== > +bool RenderHTMLCanvas::requiresLayer() const > +{ > + if (RenderReplaced::requiresLayer()) > + return true; > + > +#if ENABLE(3D_CANVAS) > + HTMLCanvasElement* canvas = reinterpret_cast<HTMLCanvasElement*>(node()); I think a static_cast<> should work there > Index: WebCore/rendering/RenderLayerBacking.cpp > =================================================================== > +#if ENABLE(3D_CANVAS) > + else if (renderer()->isCanvas()) { > + HTMLCanvasElement* canvas = reinterpret_cast<HTMLCanvasElement*>(renderer()->node()); static_cast<> > + if (canvas->context3D()) { > + m_graphicsLayer->setContentsTo3DCanvas(canvas->context3D(), canvas->texture3D()); > + m_graphicsLayer->setDrawsContent(true); Why setDrawsContent(true)? That means we'll create backing store for the primary layer, which you don't want. Have you tested borders, outlines etc. on a 3d canvas? You should include some layout tests with pixel results that verify the rendering of these. > +#if ENABLE(3D_CANVAS) > + bool is3DCanvas = false; > + if (renderer()->isCanvas()) { > + HTMLCanvasElement* canvas = reinterpret_cast<HTMLCanvasElement*>(renderer()->node()); > + is3DCanvas = canvas->is3D(); > + } > + if (is3DCanvas) > + return true; Seems like you could eliminate is3DCanvas and just do an earlier return here. In fact, if you know it's a canvas, you can always return. > void RenderLayerBacking::rendererContentChanged() > { > - if (canUseDirectCompositing() && renderer()->isImage()) > - updateImageContents(); > + if (canUseDirectCompositing()) { > + if (renderer()->isImage()) > + updateImageContents(); > + else { > +#if ENABLE(3D_CANVAS) > + if (renderer()->isCanvas()) { > + HTMLCanvasElement* canvas = reinterpret_cast<HTMLCanvasElement*>(renderer()->node()); static_cast<> > Index: WebCore/rendering/RenderLayerCompositor.cpp > =================================================================== > bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const > { > +#if ENABLE(3D_CANVAS) > + bool is3DCanvas = false; > + if (layer->renderer()->isCanvas()) { > + HTMLCanvasElement* canvas = reinterpret_cast<HTMLCanvasElement*>(layer->renderer()->node()); > + is3DCanvas = canvas->is3D(); > + } > +#endif I'd prefer this be wrapped up in its own method, requiresCompositingForCanvs(). > Index: LayoutTests/fast/dom/Window/window-properties.html > =================================================================== > --- LayoutTests/fast/dom/Window/window-properties.html (revision 47753) > +++ LayoutTests/fast/dom/Window/window-properties.html (working copy) > @@ -60,7 +60,9 @@ var __skip__ = { > "window.objCPlugin" : 1, > "window.objCPluginFunction" : 1, > "window.plainText" : 1, > - "window.textInputController" : 1 > + "window.textInputController" : 1, > + > + "window.CanvasRenderingContext3D" : 1 // We ignore CanvasRenderingContext3D and test it elsewhere, since it is not in all builds Any reason for the blank line? r- for lack of some basic tests and the few quibbles noted above. It's mostly good though.
Chris Marrin
Comment 50 2009-08-27 16:56:18 PDT
Sending LayoutTests/ChangeLog Adding LayoutTests/fast/canvas/change-context-expected.txt Adding LayoutTests/fast/canvas/change-context.html Sending LayoutTests/fast/dom/Window/window-properties.html Sending LayoutTests/fast/dom/resources/prototype-inheritance-2.js Sending LayoutTests/fast/dom/resources/prototype-inheritance.js Sending WebCore/ChangeLog Sending WebCore/WebCore.xcodeproj/project.pbxproj Sending WebCore/bindings/js/JSCanvasRenderingContext3DCustom.cpp Sending WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp Sending WebCore/dom/Element.cpp Sending WebCore/dom/Node.cpp Sending WebCore/dom/Node.h Sending WebCore/html/HTMLCanvasElement.cpp Sending WebCore/html/HTMLCanvasElement.h Sending WebCore/html/canvas/CanvasBuffer.cpp Sending WebCore/html/canvas/CanvasBuffer.h Sending WebCore/html/canvas/CanvasFramebuffer.cpp Sending WebCore/html/canvas/CanvasFramebuffer.h Sending WebCore/html/canvas/CanvasObject.cpp Sending WebCore/html/canvas/CanvasObject.h Sending WebCore/html/canvas/CanvasProgram.cpp Sending WebCore/html/canvas/CanvasProgram.h Sending WebCore/html/canvas/CanvasRenderbuffer.cpp Sending WebCore/html/canvas/CanvasRenderbuffer.h Sending WebCore/html/canvas/CanvasRenderingContext3D.cpp Sending WebCore/html/canvas/CanvasRenderingContext3D.h Sending WebCore/html/canvas/CanvasShader.cpp Sending WebCore/html/canvas/CanvasShader.h Sending WebCore/html/canvas/CanvasTexture.cpp Sending WebCore/html/canvas/CanvasTexture.h Sending WebCore/page/DOMWindow.idl Sending WebCore/page/animation/AnimationBase.cpp Sending WebCore/page/animation/AnimationController.cpp Sending WebCore/platform/graphics/GraphicsContext3D.h Sending WebCore/platform/graphics/GraphicsLayer.h Sending WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp Sending WebCore/platform/graphics/mac/GraphicsLayerCA.h Sending WebCore/platform/graphics/mac/GraphicsLayerCA.mm Sending WebCore/rendering/RenderHTMLCanvas.cpp Sending WebCore/rendering/RenderHTMLCanvas.h Sending WebCore/rendering/RenderLayerBacking.cpp Sending WebCore/rendering/RenderLayerCompositor.cpp Sending WebCore/rendering/RenderLayerCompositor.h Sending WebCore/rendering/RenderObject.h Transmitting file data ............................................. Committed revision 47843.
Chris Marrin
Comment 51 2009-08-27 16:56:48 PDT
Comment on attachment 38667 [details] Final patch for Canvas3D work Simon hand reviewed this and it is now landed
Note You need to log in before you can comment on or make changes to this bug.