summaryrefslogtreecommitdiffstats
path: root/WebCore/html
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html')
-rw-r--r--WebCore/html/DOMSettableTokenList.cpp9
-rw-r--r--WebCore/html/HTMLFormControlElement.cpp59
-rw-r--r--WebCore/html/HTMLFormControlElement.h10
-rw-r--r--WebCore/html/HTMLFormElement.cpp6
-rw-r--r--WebCore/html/HTMLFrameElementBase.cpp5
-rw-r--r--WebCore/html/HTMLInputElement.cpp2
-rw-r--r--WebCore/html/HTMLLinkElement.cpp10
-rw-r--r--WebCore/html/HTMLMediaElement.cpp12
-rw-r--r--WebCore/html/HTMLOutputElement.cpp137
-rw-r--r--WebCore/html/HTMLOutputElement.h73
-rw-r--r--WebCore/html/HTMLOutputElement.idl43
-rw-r--r--WebCore/html/HTMLTableElement.cpp4
-rw-r--r--WebCore/html/HTMLTagNames.in1
-rw-r--r--WebCore/html/ValidationMessage.cpp70
-rw-r--r--WebCore/html/ValidationMessage.h61
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.cpp9
-rw-r--r--WebCore/html/canvas/WebGLContextEvent.cpp54
-rw-r--r--WebCore/html/canvas/WebGLContextEvent.h58
-rw-r--r--WebCore/html/canvas/WebGLContextEvent.idl36
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.cpp132
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.h35
-rw-r--r--WebCore/html/canvas/WebGLRenderbuffer.cpp3
-rw-r--r--WebCore/html/canvas/WebGLRenderbuffer.h19
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.cpp652
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.h26
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.idl12
-rw-r--r--WebCore/html/parser/HTMLTreeBuilder.cpp9
27 files changed, 1319 insertions, 228 deletions
diff --git a/WebCore/html/DOMSettableTokenList.cpp b/WebCore/html/DOMSettableTokenList.cpp
index 2636bd3..3a86e9c 100644
--- a/WebCore/html/DOMSettableTokenList.cpp
+++ b/WebCore/html/DOMSettableTokenList.cpp
@@ -40,7 +40,7 @@ DOMSettableTokenList::~DOMSettableTokenList()
const AtomicString DOMSettableTokenList::item(unsigned index) const
{
if (index >= length())
- return AtomicString("");
+ return AtomicString();
return m_tokens[index];
}
@@ -61,7 +61,10 @@ void DOMSettableTokenList::add(const AtomicString& token, ExceptionCode& ec)
void DOMSettableTokenList::addInternal(const AtomicString& token)
{
m_value = addToken(m_value, token);
- m_tokens.add(token);
+ if (m_tokens.isNull())
+ m_tokens.set(token, false);
+ else
+ m_tokens.add(token);
}
void DOMSettableTokenList::remove(const AtomicString& token, ExceptionCode& ec)
@@ -92,7 +95,7 @@ bool DOMSettableTokenList::toggle(const AtomicString& token, ExceptionCode& ec)
void DOMSettableTokenList::setValue(const String& value)
{
m_value = value;
- m_tokens.set(value, true);
+ m_tokens.set(value, false);
}
} // namespace WebCore
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index 710cda1..8fa000f 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -45,6 +45,7 @@
#include "RenderTextControl.h"
#include "RenderTheme.h"
#include "ScriptEventListener.h"
+#include "ValidationMessage.h"
#include "ValidityState.h"
#include <limits>
#include <wtf/Vector.h>
@@ -77,6 +78,12 @@ HTMLFormControlElement::~HTMLFormControlElement()
m_form->removeFormElement(this);
}
+void HTMLFormControlElement::detach()
+{
+ hideVisibleValidationMessage();
+ HTMLElement::detach();
+}
+
bool HTMLFormControlElement::formNoValidate() const
{
return !getAttribute(formnovalidateAttr).isNull();
@@ -301,7 +308,8 @@ void HTMLFormControlElement::setNeedsWillValidateCheck()
m_willValidateInitialized = true;
m_willValidate = newWillValidate;
setNeedsStyleRecalc();
- // FIXME: Show/hide a validation message.
+ if (!m_willValidate)
+ hideVisibleValidationMessage();
}
String HTMLFormControlElement::validationMessage()
@@ -309,6 +317,42 @@ String HTMLFormControlElement::validationMessage()
return validity()->validationMessage();
}
+void HTMLFormControlElement::updateVisibleValidationMessage()
+{
+ Page* page = document()->page();
+ if (!page)
+ return;
+ String message;
+ if (renderer() && willValidate()) {
+ message = validationMessage().stripWhiteSpace();
+ // HTML5 specification doesn't ask UA to show the title attribute value
+ // with the validationMessage. However, this behavior is same as Opera
+ // and the specification describes such behavior as an example.
+ const AtomicString& title = getAttribute(titleAttr);
+ if (!message.isEmpty() && !title.isEmpty()) {
+ message.append('\n');
+ message.append(title);
+ }
+ }
+ if (!m_validationMessage) {
+ m_validationMessage = ValidationMessage::create(this);
+ m_validationMessage->setMessage(message);
+ } else if (message.isEmpty())
+ hideVisibleValidationMessage();
+ else if (m_validationMessage->message() != message)
+ m_validationMessage->setMessage(message);
+}
+
+void HTMLFormControlElement::hideVisibleValidationMessage()
+{
+ m_validationMessage = 0;
+}
+
+String HTMLFormControlElement::visibleValidationMessage() const
+{
+ return m_validationMessage ? m_validationMessage->message() : String();
+}
+
bool HTMLFormControlElement::checkValidity(Vector<RefPtr<HTMLFormControlElement> >* unhandledInvalidControls)
{
if (!willValidate() || isValidFormControlElement())
@@ -338,7 +382,13 @@ void HTMLFormControlElement::setNeedsValidityCheck()
setNeedsStyleRecalc();
}
m_isValid = newIsValid;
- // FIXME: show/hide a validation message.
+
+ // Updates only if this control already has a validtion message.
+ if (!visibleValidationMessage().isEmpty()) {
+ // Calls updateVisibleValidationMessage() even if m_isValid is not
+ // changed because a validation message can be chagned.
+ updateVisibleValidationMessage();
+ }
}
void HTMLFormControlElement::setCustomValidity(const String& error)
@@ -360,6 +410,7 @@ void HTMLFormControlElement::dispatchBlurEvent()
document()->page()->chrome()->client()->formDidBlur(this);
HTMLElement::dispatchBlurEvent();
+ hideVisibleValidationMessage();
}
HTMLFormElement* HTMLFormControlElement::virtualForm() const
@@ -568,7 +619,7 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end)
WebCore::setSelectionRange(this, start, end);
}
-int HTMLTextFormControlElement::selectionStart()
+int HTMLTextFormControlElement::selectionStart() const
{
if (!isTextFormControl())
return 0;
@@ -579,7 +630,7 @@ int HTMLTextFormControlElement::selectionStart()
return toRenderTextControl(renderer())->selectionStart();
}
-int HTMLTextFormControlElement::selectionEnd()
+int HTMLTextFormControlElement::selectionEnd() const
{
if (!isTextFormControl())
return 0;
diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h
index 8b721d8..1960fc3 100644
--- a/WebCore/html/HTMLFormControlElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -31,6 +31,7 @@ namespace WebCore {
class FormDataList;
class HTMLFormElement;
class RenderTextControl;
+class ValidationMessage;
class ValidityState;
class VisibleSelection;
@@ -84,6 +85,8 @@ public:
virtual bool willValidate() const;
String validationMessage();
+ void updateVisibleValidationMessage();
+ void hideVisibleValidationMessage();
bool checkValidity(Vector<RefPtr<HTMLFormControlElement> >* unhandledInvalidControls = 0);
// This must be called when a validation constraint or control value is changed.
void setNeedsValidityCheck();
@@ -111,6 +114,7 @@ protected:
virtual void dispatchFocusEvent();
virtual void dispatchBlurEvent();
+ virtual void detach();
void removeFromForm();
@@ -131,9 +135,11 @@ private:
virtual HTMLFormElement* virtualForm() const;
virtual bool isDefaultButtonForForm() const;
virtual bool isValidFormControlElement();
+ String visibleValidationMessage() const;
HTMLFormElement* m_form;
OwnPtr<ValidityState> m_validityState;
+ OwnPtr<ValidationMessage> m_validationMessage;
bool m_disabled : 1;
bool m_readOnly : 1;
bool m_required : 1;
@@ -182,8 +188,8 @@ public:
String strippedPlaceholder() const;
bool placeholderShouldBeVisible() const;
- int selectionStart();
- int selectionEnd();
+ int selectionStart() const;
+ int selectionEnd() const;
void setSelectionStart(int);
void setSelectionEnd(int);
void select();
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index 31a72bd..da388d5 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -205,6 +205,9 @@ bool HTMLFormElement::validateInteractively(Event* event)
if (submitElement && submitElement->formNoValidate())
return true;
+ for (unsigned i = 0; i < m_associatedElements.size(); ++i)
+ m_associatedElements[i]->hideVisibleValidationMessage();
+
Vector<RefPtr<HTMLFormControlElement> > unhandledInvalidControls;
collectUnhandledInvalidControls(unhandledInvalidControls);
if (unhandledInvalidControls.isEmpty())
@@ -212,7 +215,7 @@ bool HTMLFormElement::validateInteractively(Event* event)
// If the form has invalid controls, abort submission.
RefPtr<HTMLFormElement> protector(this);
- // Focus on the first focusable control.
+ // Focus on the first focusable control and show a validation message.
for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) {
HTMLFormControlElement* unhandled = unhandledInvalidControls[i].get();
if (unhandled->isFocusable() && unhandled->inDocument()) {
@@ -223,6 +226,7 @@ bool HTMLFormElement::validateInteractively(Event* event)
// moved to another document.
if (unhandled->isFocusable() && unhandled->inDocument() && originalDocument == unhandled->document()) {
unhandled->focus();
+ unhandled->updateVisibleValidationMessage();
break;
}
}
diff --git a/WebCore/html/HTMLFrameElementBase.cpp b/WebCore/html/HTMLFrameElementBase.cpp
index d153845..cba82a2 100644
--- a/WebCore/html/HTMLFrameElementBase.cpp
+++ b/WebCore/html/HTMLFrameElementBase.cpp
@@ -92,8 +92,6 @@ bool HTMLFrameElementBase::isURLAllowed() const
void HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList)
{
- ASSERT(!m_frameName.isEmpty());
-
if (!isURLAllowed())
return;
@@ -155,9 +153,6 @@ void HTMLFrameElementBase::setName()
m_frameName = getAttribute(nameAttr);
if (m_frameName.isNull())
m_frameName = getIdAttribute();
-
- if (Frame* parentFrame = document()->frame())
- m_frameName = parentFrame->tree()->uniqueChildName(m_frameName);
}
void HTMLFrameElementBase::setNameAndOpenURL()
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index cd826bf..b7b05b1 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -338,7 +338,7 @@ bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
if (deprecatedInputType() == RADIO) {
// When using Spatial Navigation, every radio button should be focusable.
- if (document()->frame() && document()->frame()->settings() && document()->frame()->settings()->isSpatialNavigationEnabled())
+ if (isSpatialNavigationEnabled(document()->frame()))
return true;
// Never allow keyboard tabbing to leave you in the same radio group. Always
diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp
index 6a5c2f6..9303076 100644
--- a/WebCore/html/HTMLLinkElement.cpp
+++ b/WebCore/html/HTMLLinkElement.cpp
@@ -199,6 +199,7 @@ void HTMLLinkElement::process()
if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty())
document()->setIconURL(m_url.string(), type);
+<<<<<<< HEAD
#ifdef ANDROID_APPLE_TOUCH_ICON
if ((m_relAttribute.m_isTouchIcon || m_relAttribute.m_isPrecomposedTouchIcon) && m_url.isValid()
&& !m_url.isEmpty() && document()->frame())
@@ -209,6 +210,15 @@ void HTMLLinkElement::process()
if (m_relAttribute.m_isDNSPrefetch && document()->isDNSPrefetchEnabled() && m_url.isValid() && !m_url.isEmpty())
ResourceHandle::prepareForURL(m_url);
+=======
+ if (m_relAttribute.m_isDNSPrefetch) {
+ Settings* settings = document()->settings();
+ // FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt
+ // to complete that as URL <https://bugs.webkit.org/show_bug.cgi?id=48857>.
+ if (settings && settings->dnsPrefetchingEnabled() && m_url.isValid() && !m_url.isEmpty())
+ ResourceHandle::prepareForURL(m_url);
+ }
+>>>>>>> webkit.org at r71558
#if ENABLE(LINK_PREFETCH)
if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame())
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index 3f6c286..5b75dde 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -1119,6 +1119,18 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
float earliestTime = m_player->startTime();
time = max(time, earliestTime);
+ // Ask the media engine for the time value in the movie's time scale before comparing with current time. This
+ // is necessary because if the seek time is not equal to currentTime but the delta is less than the movie's
+ // time scale, we will ask the media engine to "seek" to the current movie time, which may be a noop and
+ // not generate a timechanged callback. This means m_seeking will never be cleared and we will never
+ // fire a 'seeked' event.
+#if !LOG_DISABLED
+ float mediaTime = m_player->mediaTimeForTimeValue(time);
+ if (time != mediaTime)
+ LOG(Media, "HTMLMediaElement::seek(%f) - media timeline equivalent is %f", time, mediaTime);
+#endif
+ time = m_player->mediaTimeForTimeValue(time);
+
// 7 - If the (possibly now changed) new playback position is not in one of the ranges given in the
// seekable attribute, then let it be the position in one of the ranges given in the seekable attribute
// that is the nearest to the new playback position. ... If there are no ranges given in the seekable
diff --git a/WebCore/html/HTMLOutputElement.cpp b/WebCore/html/HTMLOutputElement.cpp
new file mode 100644
index 0000000..dee21ae
--- /dev/null
+++ b/WebCore/html/HTMLOutputElement.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLOutputElement.h"
+
+#include "HTMLFormElement.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
+ , m_isDefaultValueMode(true)
+ , m_isSetTextContentInProgress(false)
+ , m_defaultValue()
+ , m_tokens(DOMSettableTokenList::create())
+{
+}
+
+PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+{
+ return adoptRef(new HTMLOutputElement(tagName, document, form));
+}
+
+const AtomicString& HTMLOutputElement::formControlType() const
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, output, ("output"));
+ return output;
+}
+
+void HTMLOutputElement::parseMappedAttribute(Attribute* attr)
+{
+ // FIXME: Should handle the 'form' attribute here.
+ if (attr->name() == HTMLNames::forAttr)
+ setFor(attr->value());
+ else
+ HTMLFormControlElement::parseMappedAttribute(attr);
+}
+
+DOMSettableTokenList* HTMLOutputElement::htmlFor() const
+{
+ return m_tokens.get();
+}
+
+void HTMLOutputElement::setFor(const String& value)
+{
+ m_tokens->setValue(value);
+}
+
+void HTMLOutputElement::setForm(const String& /*id*/)
+{
+ // FIXME: Implement this function.
+}
+
+void HTMLOutputElement::childrenChanged(bool createdByParser, Node*, Node*, int)
+{
+ if (createdByParser || m_isSetTextContentInProgress) {
+ m_isSetTextContentInProgress = false;
+ return;
+ }
+
+ if (m_isDefaultValueMode)
+ m_defaultValue = textContent();
+}
+
+void HTMLOutputElement::reset()
+{
+ // The reset algorithm for output elements is to set the element's
+ // value mode flag to "default" and then to set the element's textContent
+ // attribute to the default value.
+ m_isDefaultValueMode = true;
+ setTextContentInternal(m_defaultValue);
+}
+
+String HTMLOutputElement::value() const
+{
+ return textContent();
+}
+
+void HTMLOutputElement::setValue(const String& value)
+{
+ // The value mode flag set to "value" when the value attribute is set.
+ m_isDefaultValueMode = false;
+ setTextContentInternal(value);
+}
+
+String HTMLOutputElement::defaultValue() const
+{
+ return m_defaultValue;
+}
+
+void HTMLOutputElement::setDefaultValue(const String& value)
+{
+ m_defaultValue = value;
+ // The spec requires the value attribute set to the default value
+ // when the element's value mode flag to "default".
+ if (m_isDefaultValueMode)
+ setTextContentInternal(value);
+}
+
+void HTMLOutputElement::setTextContentInternal(const String& value)
+{
+ ASSERT(!m_isSetTextContentInProgress);
+ ExceptionCode ec;
+ m_isSetTextContentInProgress = true;
+ setTextContent(value, ec);
+}
+
+} // namespace
diff --git a/WebCore/html/HTMLOutputElement.h b/WebCore/html/HTMLOutputElement.h
new file mode 100644
index 0000000..df807fb
--- /dev/null
+++ b/WebCore/html/HTMLOutputElement.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLOutputElement_h
+#define HTMLOutputElement_h
+
+#include "DOMSettableTokenList.h"
+#include "HTMLFormControlElement.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class HTMLOutputElement : public HTMLFormControlElement {
+public:
+ static PassRefPtr<HTMLOutputElement> create(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual bool willValidate() const { return false; }
+
+ void setForm(const String&);
+ String value() const;
+ void setValue(const String&);
+ String defaultValue() const;
+ void setDefaultValue(const String&);
+ void setFor(const String&);
+ DOMSettableTokenList* htmlFor() const;
+
+private:
+ HTMLOutputElement(const QualifiedName&, Document*, HTMLFormElement*);
+
+ virtual void parseMappedAttribute(Attribute*);
+ virtual const AtomicString& formControlType() const;
+ virtual bool isEnumeratable() const { return true; }
+ virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void reset();
+
+ void setTextContentInternal(const String&);
+
+ bool m_isDefaultValueMode;
+ bool m_isSetTextContentInProgress;
+ String m_defaultValue;
+ RefPtr<DOMSettableTokenList> m_tokens;
+};
+
+} // namespace
+
+#endif
diff --git a/WebCore/html/HTMLOutputElement.idl b/WebCore/html/HTMLOutputElement.idl
new file mode 100644
index 0000000..4e6cbfb
--- /dev/null
+++ b/WebCore/html/HTMLOutputElement.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Google 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface HTMLOutputElement : HTMLElement {
+ attribute [Custom] DOMSettableTokenList htmlFor;
+ readonly attribute HTMLFormElement form;
+ attribute [Reflect] DOMString name;
+
+ readonly attribute DOMString type;
+ attribute [ConvertNullToNullString] DOMString defaultValue;
+ attribute [ConvertNullToNullString] DOMString value;
+
+ readonly attribute boolean willValidate;
+ readonly attribute ValidityState validity;
+ readonly attribute DOMString validationMessage;
+ boolean checkValidity();
+ void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
+
+ readonly attribute NodeList labels;
+ };
+}
diff --git a/WebCore/html/HTMLTableElement.cpp b/WebCore/html/HTMLTableElement.cpp
index fe823ea..f6344d4 100644
--- a/WebCore/html/HTMLTableElement.cpp
+++ b/WebCore/html/HTMLTableElement.cpp
@@ -424,8 +424,8 @@ void HTMLTableElement::parseMappedAttribute(Attribute* attr)
} else if (attr->name() == alignAttr) {
if (!attr->value().isEmpty()) {
if (equalIgnoringCase(attr->value(), "center")) {
- addCSSProperty(attr, CSSPropertyMarginLeft, CSSValueAuto);
- addCSSProperty(attr, CSSPropertyMarginRight, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyWebkitMarginStart, CSSValueAuto);
+ addCSSProperty(attr, CSSPropertyWebkitMarginEnd, CSSValueAuto);
} else
addCSSProperty(attr, CSSPropertyFloat, attr->value());
}
diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in
index 209636d..2b2c1fe 100644
--- a/WebCore/html/HTMLTagNames.in
+++ b/WebCore/html/HTMLTagNames.in
@@ -93,6 +93,7 @@ object constructorNeedsCreatedByParser
ol interfaceName=HTMLOListElement
optgroup interfaceName=HTMLOptGroupElement, constructorNeedsFormElement
option constructorNeedsFormElement
+output constructorNeedsFormElement
p interfaceName=HTMLParagraphElement
param
plaintext interfaceName=HTMLElement
diff --git a/WebCore/html/ValidationMessage.cpp b/WebCore/html/ValidationMessage.cpp
new file mode 100644
index 0000000..d32917e
--- /dev/null
+++ b/WebCore/html/ValidationMessage.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ValidationMessage.h"
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ALWAYS_INLINE ValidationMessage::ValidationMessage(HTMLFormControlElement* element)
+ : m_element(element)
+{
+}
+
+ValidationMessage::~ValidationMessage()
+{
+ hideMessage();
+}
+
+PassOwnPtr<ValidationMessage> ValidationMessage::create(HTMLFormControlElement* element)
+{
+ return adoptPtr(new ValidationMessage(element));
+}
+
+void ValidationMessage::setMessage(const String& message)
+{
+ // FIXME: Construct validation message UI if m_message is empty.
+
+ m_message = message;
+
+ m_timer.set(new Timer<ValidationMessage>(this, &ValidationMessage::hideMessage));
+ m_timer->startOneShot(6.0); // FIXME: should be <message length> * something.
+}
+
+void ValidationMessage::hideMessage(Timer<ValidationMessage>*)
+{
+ // FIXME: Implement.
+
+ m_message = String();
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/ValidationMessage.h b/WebCore/html/ValidationMessage.h
new file mode 100644
index 0000000..fe18b6b
--- /dev/null
+++ b/WebCore/html/ValidationMessage.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ValidationMessage_h
+#define ValidationMessage_h
+
+#include "Timer.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class HTMLFormControlElement;
+
+class ValidationMessage : public Noncopyable {
+public:
+ static PassOwnPtr<ValidationMessage> create(HTMLFormControlElement*);
+ ~ValidationMessage();
+ String message() const { return m_message; }
+ void setMessage(const String&);
+
+private:
+ ValidationMessage(HTMLFormControlElement*);
+ void hideMessage(Timer<ValidationMessage>* = 0);
+
+ HTMLFormControlElement* m_element;
+ String m_message;
+ OwnPtr<Timer<ValidationMessage> > m_timer;
+};
+
+} // namespace WebCore
+
+#endif // ValidationMessage_h
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index b1d7b23..a2d9e98 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1582,6 +1582,15 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy,
return 0;
}
+ if (sw < 0) {
+ sx += sw;
+ sw = -sw;
+ }
+ if (sh < 0) {
+ sy += sh;
+ sh = -sh;
+ }
+
FloatRect unscaledRect(sx, sy, sw, sh);
IntRect scaledRect = canvas()->convertLogicalToDevice(unscaledRect);
if (scaledRect.width() < 1)
diff --git a/WebCore/html/canvas/WebGLContextEvent.cpp b/WebCore/html/canvas/WebGLContextEvent.cpp
new file mode 100644
index 0000000..b7a277f
--- /dev/null
+++ b/WebCore/html/canvas/WebGLContextEvent.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Google 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebGLContextEvent.h"
+
+namespace WebCore {
+
+WebGLContextEvent::WebGLContextEvent()
+{
+}
+
+WebGLContextEvent::WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ : Event(type, canBubble, cancelable)
+ , m_statusMessage(statusMessage)
+{
+}
+
+WebGLContextEvent::~WebGLContextEvent()
+{
+}
+
+void WebGLContextEvent::initEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+{
+ if (dispatched())
+ return;
+
+ Event::initEvent(type, canBubble, cancelable);
+ m_statusMessage = statusMessage;
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLContextEvent.h b/WebCore/html/canvas/WebGLContextEvent.h
new file mode 100644
index 0000000..348769b
--- /dev/null
+++ b/WebCore/html/canvas/WebGLContextEvent.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Google 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLContextEvent_h
+#define WebGLContextEvent_h
+
+#include "Event.h"
+
+namespace WebCore {
+
+class WebGLContextEvent : public Event {
+public:
+ static PassRefPtr<WebGLContextEvent> create()
+ {
+ return adoptRef(new WebGLContextEvent);
+ }
+ static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ {
+ return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ }
+ virtual ~WebGLContextEvent();
+
+ void initEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
+
+ const String& statusMessage() const { return m_statusMessage; }
+
+private:
+ WebGLContextEvent();
+ WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
+
+ String m_statusMessage;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextEvent_h
diff --git a/WebCore/html/canvas/WebGLContextEvent.idl b/WebCore/html/canvas/WebGLContextEvent.idl
new file mode 100644
index 0000000..30973a9
--- /dev/null
+++ b/WebCore/html/canvas/WebGLContextEvent.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Google 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+ interface [
+ Conditional=3D_CANVAS,
+ ] WebGLContextEvent : Event {
+ readonly attribute DOMString statusMessage;
+ [StrictTypeChecking] void initEvent(in DOMString eventTypeArg,
+ in boolean canBubbleArg,
+ in boolean cancelableArg,
+ in DOMString statusMessageArg);
+ };
+}
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 0fdcb99..5bf3779 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -32,7 +32,42 @@
#include "WebGLRenderingContext.h"
namespace WebCore {
-
+
+namespace {
+
+ // This function is only for depth/stencil/depth_stencil attachment.
+ // Currently we assume these attachments are all renderbuffers.
+ unsigned long getInternalFormat(WebGLObject* buffer)
+ {
+ ASSERT(buffer && buffer->isRenderbuffer());
+ return (reinterpret_cast<WebGLRenderbuffer*>(buffer))->getInternalFormat();
+ }
+
+ bool isUninitialized(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
+ && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
+ return true;
+ return false;
+ }
+
+ void setInitialized(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
+ (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
+ }
+
+ bool isValid(WebGLObject* attachedObject)
+ {
+ if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) {
+ if (!(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isValid())
+ return false;
+ }
+ return true;
+ }
+
+} // anonymous namespace
+
PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
{
return adoptRef(new WebGLFramebuffer(ctx));
@@ -66,7 +101,24 @@ void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLObject* atta
default:
return;
}
- initializeRenderbuffers();
+}
+
+WebGLObject* WebGLFramebuffer::getAttachment(unsigned long attachment) const
+{
+ if (!object())
+ return 0;
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ return m_colorAttachment.get();
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ return m_depthAttachment.get();
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ return m_stencilAttachment.get();
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ return m_depthStencilAttachment.get();
+ default:
+ return 0;
+ }
}
void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
@@ -83,25 +135,9 @@ void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
m_depthStencilAttachment = 0;
else
return;
- initializeRenderbuffers();
-}
-
-void WebGLFramebuffer::onBind()
-{
- initializeRenderbuffers();
}
-void WebGLFramebuffer::onAttachedObjectChange(WebGLObject* object)
-{
- // Currently object == 0 is not considered, but this might change if the
- // lifespan of WebGLObject changes.
- if (object
- && (object == m_colorAttachment.get() || object == m_depthAttachment.get()
- || object == m_stencilAttachment.get() || object == m_depthStencilAttachment.get()))
- initializeRenderbuffers();
-}
-
-unsigned long WebGLFramebuffer::getColorBufferFormat()
+unsigned long WebGLFramebuffer::getColorBufferFormat() const
{
if (object() && m_colorAttachment && m_colorAttachment->object()) {
if (m_colorAttachment->isRenderbuffer()) {
@@ -119,6 +155,38 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
return 0;
}
+bool WebGLFramebuffer::isIncomplete(bool checkInternalFormat) const
+{
+ unsigned int count = 0;
+ if (isDepthAttached()) {
+ if (checkInternalFormat && getInternalFormat(m_depthAttachment.get()) != GraphicsContext3D::DEPTH_COMPONENT16)
+ return true;
+ count++;
+ }
+ if (isStencilAttached()) {
+ if (checkInternalFormat && getInternalFormat(m_stencilAttachment.get()) != GraphicsContext3D::STENCIL_INDEX8)
+ return true;
+ count++;
+ }
+ if (isDepthStencilAttached()) {
+ if (checkInternalFormat && getInternalFormat(m_depthStencilAttachment.get()) != GraphicsContext3D::DEPTH_STENCIL)
+ return true;
+ if (!isValid(m_depthStencilAttachment.get()))
+ return true;
+ count++;
+ }
+ if (count > 1)
+ return true;
+ return false;
+}
+
+bool WebGLFramebuffer::onAccess()
+{
+ if (isIncomplete(true))
+ return false;
+ return initializeRenderbuffers();
+}
+
void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
{
if (!isDeleted())
@@ -129,24 +197,11 @@ void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
m_depthStencilAttachment = 0;
}
-bool WebGLFramebuffer::isUninitialized(WebGLObject* attachedObject)
+bool WebGLFramebuffer::initializeRenderbuffers()
{
- if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
- && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
- return true;
- return false;
-}
-
-void WebGLFramebuffer::setInitialized(WebGLObject* attachedObject)
-{
- if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
- (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
-}
-
-void WebGLFramebuffer::initializeRenderbuffers()
-{
- if (!object())
- return;
+ ASSERT(object());
+ if (!isColorAttached())
+ return false;
bool initColor = false, initDepth = false, initStencil = false;
unsigned long mask = 0;
if (isUninitialized(m_colorAttachment.get())) {
@@ -167,13 +222,13 @@ void WebGLFramebuffer::initializeRenderbuffers()
mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT);
}
if (!initColor && !initDepth && !initStencil)
- return;
+ return true;
// We only clear un-initialized renderbuffers when they are ready to be
// read, i.e., when the framebuffer is complete.
GraphicsContext3D* g3d = context()->graphicsContext3D();
if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
- return;
+ return false;
float colorClearValue[] = {0, 0, 0, 0}, depthClearValue = 0;
int stencilClearValue = 0;
@@ -237,6 +292,7 @@ void WebGLFramebuffer::initializeRenderbuffers()
if (initStencil)
setInitialized(m_stencilAttachment.get());
}
+ return true;
}
}
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index 1892694..394b770 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -39,27 +39,22 @@ public:
static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
- bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
- bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
- bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
-
void setAttachment(unsigned long, WebGLObject*);
// If an object is attached to the framebuffer, remove it.
void removeAttachment(WebGLObject*);
+ WebGLObject* getAttachment(unsigned long) const;
- // This function is called right after a framebuffer is bound.
- // Because renderbuffers and textures attached to the framebuffer might
- // have changed and the framebuffer might have become complete when it
- // isn't bound, so we need to clear un-initialized renderbuffers.
- void onBind();
+ unsigned long getColorBufferFormat() const;
- // When a texture or a renderbuffer changes, we need to check the
- // current bound framebuffer; if the newly changed object is attached
- // to the framebuffer and the framebuffer becomes complete, we need to
- // clear un-initialized renderbuffers.
- void onAttachedObjectChange(WebGLObject*);
+ // This should always be called before drawArray, drawElements, clear,
+ // readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is
+ // currently bound.
+ // Return false if the framebuffer is incomplete; otherwise initialize
+ // the buffers if they haven't been initialized.
+ bool onAccess();
- unsigned long getColorBufferFormat();
+ // Return false does not mean COMPLETE, might still be INCOMPLETE.
+ bool isIncomplete(bool checkInternalFormat) const;
protected:
WebGLFramebuffer(WebGLRenderingContext*);
@@ -69,9 +64,13 @@ protected:
private:
virtual bool isFramebuffer() const { return true; }
- bool isUninitialized(WebGLObject*);
- void setInitialized(WebGLObject*);
- void initializeRenderbuffers();
+ // Return false if framebuffer is incomplete.
+ bool initializeRenderbuffers();
+
+ bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); }
+ bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
+ bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
+ bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
RefPtr<WebGLObject> m_colorAttachment;
RefPtr<WebGLObject> m_depthAttachment;
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.cpp b/WebCore/html/canvas/WebGLRenderbuffer.cpp
index 4772873..b9efd47 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -42,6 +42,9 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
: WebGLObject(ctx)
, m_internalFormat(GraphicsContext3D::RGBA4)
, m_initialized(false)
+ , m_width(0)
+ , m_height(0)
+ , m_isValid(true)
{
setObject(context()->graphicsContext3D()->createRenderbuffer());
}
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.h b/WebCore/html/canvas/WebGLRenderbuffer.h
index 5765061..9a23ca5 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.h
+++ b/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -39,9 +39,24 @@ public:
static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
- void setInternalFormat(unsigned long internalformat) { m_internalFormat = internalformat; }
+ void setInternalFormat(unsigned long internalformat)
+ {
+ m_internalFormat = internalformat;
+ m_initialized = false;
+ }
unsigned long getInternalFormat() const { return m_internalFormat; }
+ void setSize(unsigned long width, unsigned long height)
+ {
+ m_width = width;
+ m_height = height;
+ }
+ unsigned long getWidth() const { return m_width; }
+ unsigned long getHeight() const { return m_height; }
+
+ void setIsValid(bool isValid) { m_isValid = isValid; }
+ bool isValid() const { return m_isValid; }
+
bool isInitialized() const { return m_initialized; }
void setInitialized() { m_initialized = true; }
@@ -55,6 +70,8 @@ private:
unsigned long m_internalFormat;
bool m_initialized;
+ unsigned long m_width, m_height;
+ bool m_isValid; // This is only false if internalFormat is DEPTH_STENCIL and packed_depth_stencil is not supported.
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 0b89cce..94dac10 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -34,6 +34,7 @@
#include "CheckedInt.h"
#include "Console.h"
#include "DOMWindow.h"
+#include "Extensions3D.h"
#include "FrameView.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
@@ -48,6 +49,7 @@
#include "WebGLActiveInfo.h"
#include "WebGLBuffer.h"
#include "WebGLContextAttributes.h"
+#include "WebGLContextEvent.h"
#include "WebGLFramebuffer.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
@@ -90,8 +92,10 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
GraphicsContext3D::Attributes emptyAttributes;
RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs ? attrs->attributes() : emptyAttributes, hostWindow));
- if (!context)
+ if (!context) {
+ canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent, false, true, "Could not create a WebGL context."));
return 0;
+ }
return new WebGLRenderingContext(canvas, context);
}
@@ -99,32 +103,41 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context)
: CanvasRenderingContext(passedCanvas)
, m_context(context)
- , m_needsUpdate(true)
- , m_markedCanvasDirty(false)
- , m_activeTextureUnit(0)
, m_videoCache(4)
- , m_packAlignment(4)
- , m_unpackAlignment(4)
- , m_unpackFlipY(false)
- , m_unpackPremultiplyAlpha(false)
+ , m_contextLost(false)
+ , m_stencilMask(0xFFFFFFFF)
+ , m_stencilFuncRef(0)
+ , m_stencilFuncMask(0xFFFFFFFF)
{
ASSERT(m_context);
+ initializeNewContext();
+}
+
+void WebGLRenderingContext::initializeNewContext()
+{
+ m_needsUpdate = true;
+ m_markedCanvasDirty = false;
+ m_activeTextureUnit = 0;
+ m_packAlignment = 4;
+ m_unpackAlignment = 4;
+ m_unpackFlipY = false;
+ m_unpackPremultiplyAlpha = false;
+ m_boundArrayBuffer = 0;
+ m_boundElementArrayBuffer = 0;
+ m_currentProgram = 0;
+ m_framebufferBinding = 0;
+ m_renderbufferBinding = 0;
+ m_vertexAttribState.clear();
int numCombinedTextureImageUnits = 0;
m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+ m_textureUnits.clear();
m_textureUnits.resize(numCombinedTextureImageUnits);
int numVertexAttribs = 0;
m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
m_maxVertexAttribs = numVertexAttribs;
- int implementationColorReadFormat = GraphicsContext3D::RGBA;
- m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT, &implementationColorReadFormat);
- m_implementationColorReadFormat = implementationColorReadFormat;
- int implementationColorReadType = GraphicsContext3D::UNSIGNED_BYTE;
- m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType);
- m_implementationColorReadType = implementationColorReadType;
-
m_maxTextureSize = 0;
m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
@@ -136,6 +149,12 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
createFallbackBlackTextures1x1();
if (!isGLES2Compliant())
initVertexAttrib0();
+
+ if (isGLES2Compliant())
+ m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_OES_packed_depth_stencil");
+ else
+ m_isDepthStencilSupported = m_context->getExtensions()->supports("GL_EXT_packed_depth_stencil");
+
m_context->reshape(canvas()->width(), canvas()->height());
m_context->viewport(0, 0, canvas()->width(), canvas()->height());
}
@@ -199,6 +218,8 @@ int WebGLRenderingContext::sizeInBytes(int type)
void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return;
@@ -211,7 +232,7 @@ void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode&
void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program) || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
return;
if (!program->attachShader(shader)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
@@ -225,7 +246,7 @@ void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* sha
void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return;
m_context->bindAttribLocation(objectOrZero(program), index, name);
cleanupAfterGraphicsCall(false);
@@ -234,6 +255,8 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned l
void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (buffer && buffer->context() != this) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
@@ -262,6 +285,8 @@ void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer
void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (buffer && buffer->context() != this) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
@@ -272,14 +297,14 @@ void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuff
}
m_framebufferBinding = buffer;
m_context->bindFramebuffer(target, objectOrZero(buffer));
- if (m_framebufferBinding)
- m_framebufferBinding->onBind();
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (renderBuffer && renderBuffer->context() != this) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
@@ -297,6 +322,8 @@ void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbu
void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (texture && texture->context() != this) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
@@ -330,13 +357,15 @@ void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* text
void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha)
{
+ if (isContextLost())
+ return;
m_context->blendColor(red, green, blue, alpha);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::blendEquation(unsigned long mode)
{
- if (!validateBlendEquation(mode))
+ if (isContextLost() || !validateBlendEquation(mode))
return;
m_context->blendEquation(mode);
cleanupAfterGraphicsCall(false);
@@ -344,7 +373,7 @@ void WebGLRenderingContext::blendEquation(unsigned long mode)
void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
{
- if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
+ if (isContextLost() || !validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
return;
m_context->blendEquationSeparate(modeRGB, modeAlpha);
cleanupAfterGraphicsCall(false);
@@ -353,12 +382,16 @@ void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigne
void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor)
{
+ if (isContextLost() || !validateBlendFuncFactors(sfactor, dfactor))
+ return;
m_context->blendFunc(sfactor, dfactor);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
{
+ if (isContextLost() || !validateBlendFuncFactors(srcRGB, dstRGB))
+ return;
m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
cleanupAfterGraphicsCall(false);
}
@@ -366,6 +399,8 @@ void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned lon
void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
if (!buffer)
return;
@@ -383,6 +418,8 @@ void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned
void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
if (!buffer)
return;
@@ -400,6 +437,8 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data,
void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
if (!buffer)
return;
@@ -417,6 +456,8 @@ void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* da
void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
if (!buffer)
return;
@@ -434,6 +475,8 @@ void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, Arr
void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
if (!buffer)
return;
@@ -450,28 +493,40 @@ void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, Arr
unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target)
{
+ if (isContextLost())
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
if (target != GraphicsContext3D::FRAMEBUFFER) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return 0;
}
if (!m_framebufferBinding || !m_framebufferBinding->object())
return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+ if (m_framebufferBinding->isIncomplete(true))
+ return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
return m_context->checkFramebufferStatus(target);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::clear(unsigned long mask)
{
+ if (isContextLost())
+ return;
if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
m_context->clear(mask);
cleanupAfterGraphicsCall(true);
}
void WebGLRenderingContext::clearColor(double r, double g, double b, double a)
{
+ if (isContextLost())
+ return;
if (isnan(r))
r = 0;
if (isnan(g))
@@ -486,18 +541,24 @@ void WebGLRenderingContext::clearColor(double r, double g, double b, double a)
void WebGLRenderingContext::clearDepth(double depth)
{
+ if (isContextLost())
+ return;
m_context->clearDepth(depth);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::clearStencil(long s)
{
+ if (isContextLost())
+ return;
m_context->clearStencil(s);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha)
{
+ if (isContextLost())
+ return;
m_context->colorMask(red, green, blue, alpha);
cleanupAfterGraphicsCall(false);
}
@@ -505,7 +566,7 @@ void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alph
void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject(shader))
return;
m_context->compileShader(objectOrZero(shader));
cleanupAfterGraphicsCall(false);
@@ -513,6 +574,8 @@ void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec
void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
{
+ if (isContextLost())
+ return;
if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
return;
WebGLTexture* tex = validateTextureBinding(target, true);
@@ -530,16 +593,20 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
// FIXME: if the framebuffer is not complete, none of the below should be executed.
tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
- if (m_framebufferBinding)
- m_framebufferBinding->onAttachedObjectChange(tex);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
{
+ if (isContextLost())
+ return;
WebGLTexture* tex = validateTextureBinding(target, true);
if (!tex)
return;
@@ -551,12 +618,18 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
return;
}
}
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
cleanupAfterGraphicsCall(false);
}
PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
{
+ if (isContextLost())
+ return 0;
RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
addObject(o.get());
return o;
@@ -564,6 +637,8 @@ PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
{
+ if (isContextLost())
+ return 0;
RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
addObject(o.get());
return o;
@@ -571,6 +646,8 @@ PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
{
+ if (isContextLost())
+ return 0;
RefPtr<WebGLTexture> o = WebGLTexture::create(this);
addObject(o.get());
return o;
@@ -578,6 +655,8 @@ PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
{
+ if (isContextLost())
+ return 0;
RefPtr<WebGLProgram> o = WebGLProgram::create(this);
addObject(o.get());
return o;
@@ -585,6 +664,8 @@ PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
{
+ if (isContextLost())
+ return 0;
RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
addObject(o.get());
return o;
@@ -593,6 +674,8 @@ PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return 0;
if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return 0;
@@ -605,13 +688,15 @@ PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type,
void WebGLRenderingContext::cullFace(unsigned long mode)
{
+ if (isContextLost())
+ return;
m_context->cullFace(mode);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
{
- if (!buffer)
+ if (isContextLost() || !buffer)
return;
buffer->deleteObject();
@@ -633,7 +718,7 @@ void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
{
- if (!framebuffer)
+ if (isContextLost() || !framebuffer)
return;
if (framebuffer == m_framebufferBinding) {
m_framebufferBinding = 0;
@@ -645,7 +730,7 @@ void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
{
- if (!program)
+ if (isContextLost() || !program)
return;
if (program->context() != this) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
@@ -658,7 +743,7 @@ void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
{
- if (!renderbuffer)
+ if (isContextLost() || !renderbuffer)
return;
if (renderbuffer == m_renderbufferBinding)
m_renderbufferBinding = 0;
@@ -669,7 +754,7 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
void WebGLRenderingContext::deleteShader(WebGLShader* shader)
{
- if (!shader)
+ if (isContextLost() || !shader)
return;
shader->deleteObject();
@@ -677,7 +762,7 @@ void WebGLRenderingContext::deleteShader(WebGLShader* shader)
void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
{
- if (!texture)
+ if (isContextLost() || !texture)
return;
texture->deleteObject();
@@ -687,18 +772,28 @@ void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
void WebGLRenderingContext::depthFunc(unsigned long func)
{
+ if (isContextLost())
+ return;
m_context->depthFunc(func);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::depthMask(bool flag)
{
+ if (isContextLost())
+ return;
m_context->depthMask(flag);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::depthRange(double zNear, double zFar)
{
+ if (isContextLost())
+ return;
+ if (zNear > zFar) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
m_context->depthRange(zNear, zFar);
cleanupAfterGraphicsCall(false);
}
@@ -706,7 +801,7 @@ void WebGLRenderingContext::depthRange(double zNear, double zFar)
void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program) || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
return;
if (!program->detachShader(shader)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
@@ -720,7 +815,7 @@ void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* sha
void WebGLRenderingContext::disable(unsigned long cap)
{
- if (!validateCapability(cap))
+ if (isContextLost() || !validateCapability(cap))
return;
m_context->disable(cap);
cleanupAfterGraphicsCall(false);
@@ -729,6 +824,8 @@ void WebGLRenderingContext::disable(unsigned long cap)
void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (index >= m_maxVertexAttribs) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -925,7 +1022,7 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun
{
UNUSED_PARAM(ec);
- if (!validateDrawMode(mode))
+ if (isContextLost() || !validateDrawMode(mode))
return;
if (first < 0 || count < 0) {
@@ -952,6 +1049,11 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun
}
}
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+
bool vertexAttrib0Simulated = false;
if (!isGLES2Compliant())
vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
@@ -969,7 +1071,7 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
{
UNUSED_PARAM(ec);
- if (!validateDrawMode(mode))
+ if (isContextLost() || !validateDrawMode(mode))
return;
switch (type) {
@@ -1011,6 +1113,11 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
}
}
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
+
bool vertexAttrib0Simulated = false;
if (!isGLES2Compliant()) {
if (!numElements)
@@ -1029,7 +1136,7 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
void WebGLRenderingContext::enable(unsigned long cap)
{
- if (!validateCapability(cap))
+ if (isContextLost() || !validateCapability(cap))
return;
m_context->enable(cap);
cleanupAfterGraphicsCall(false);
@@ -1038,6 +1145,8 @@ void WebGLRenderingContext::enable(unsigned long cap)
void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (index >= m_maxVertexAttribs) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -1054,6 +1163,8 @@ void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, Excepti
void WebGLRenderingContext::finish()
{
+ if (isContextLost())
+ return;
m_context->finish();
cleanupAfterGraphicsCall(true);
}
@@ -1061,6 +1172,8 @@ void WebGLRenderingContext::finish()
void WebGLRenderingContext::flush()
{
+ if (isContextLost())
+ return;
m_context->flush();
cleanupAfterGraphicsCall(true);
}
@@ -1068,7 +1181,7 @@ void WebGLRenderingContext::flush()
void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateFramebufferFuncParameters(target, attachment))
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
return;
if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
@@ -1085,42 +1198,61 @@ void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsign
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
- if (buffer && buffer->object()) {
- bool isConflicted = false;
- switch (attachment) {
- case GraphicsContext3D::DEPTH_ATTACHMENT:
- if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached())
- isConflicted = true;
- if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
- isConflicted = true;
- break;
- case GraphicsContext3D::STENCIL_ATTACHMENT:
- if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached())
- isConflicted = true;
- if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
- isConflicted = true;
- break;
- case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
- if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached())
- isConflicted = true;
- if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
- isConflicted = true;
- break;
- }
- if (isConflicted) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
- return;
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ bool reattachDepth = false;
+ bool reattachStencil = false;
+ bool reattachDepthStencilDepth = false;
+ bool reattachDepthStencilStencil = false;
+ switch (attachment) {
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
+ if (!bufferObject) {
+ reattachDepth = true;
+ reattachStencil = true;
}
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ if (!bufferObject)
+ reattachDepthStencilDepth = true;
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
+ if (!bufferObject)
+ reattachDepthStencilStencil = true;
+ break;
+ default:
+ m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
}
- m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
m_framebufferBinding->setAttachment(attachment, buffer);
+ if (reattachDepth) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachStencil) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachDepthStencilDepth) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::DEPTH_ATTACHMENT, renderbuffertarget, object);
+ }
+ if (reattachDepthStencilStencil) {
+ Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT));
+ if (object)
+ m_context->framebufferRenderbuffer(target, GraphicsContext3D::STENCIL_ATTACHMENT, renderbuffertarget, object);
+ }
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateFramebufferFuncParameters(target, attachment))
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
return;
if (level) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -1144,12 +1276,16 @@ void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned
void WebGLRenderingContext::frontFace(unsigned long mode)
{
+ if (isContextLost())
+ return;
m_context->frontFace(mode);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::generateMipmap(unsigned long target)
{
+ if (isContextLost())
+ return;
WebGLTexture* tex = validateTextureBinding(target, false);
if (!tex)
return;
@@ -1178,9 +1314,9 @@ void WebGLRenderingContext::generateMipmap(unsigned long target)
PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- ActiveInfo info;
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return 0;
+ ActiveInfo info;
if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
return 0;
return WebGLActiveInfo::create(info.name, info.type, info.size);
@@ -1189,9 +1325,9 @@ PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram*
PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- ActiveInfo info;
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return 0;
+ ActiveInfo info;
if (!m_context->getActiveUniform(objectOrZero(program), index, info))
return 0;
if (!isGLES2Compliant())
@@ -1204,7 +1340,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Web
{
UNUSED_PARAM(ec);
shaderObjects.clear();
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return false;
int numShaders = 0;
m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::ATTACHED_SHADERS, &numShaders);
@@ -1229,12 +1365,16 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Web
int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
{
+ if (isContextLost())
+ return -1;
return m_context->getAttribLocation(objectOrZero(program), name);
}
WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return WebGLGetInfo();
@@ -1255,6 +1395,8 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, uns
PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
{
+ if (isContextLost())
+ return 0;
// We always need to return a new WebGLContextAttributes object to
// prevent the user from mutating any cached version.
return WebGLContextAttributes::create(m_context->getContextAttributes());
@@ -1268,7 +1410,7 @@ unsigned long WebGLRenderingContext::getError()
WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateFramebufferFuncParameters(target, attachment))
+ if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
return WebGLGetInfo();
switch (pname) {
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
@@ -1281,7 +1423,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned l
return WebGLGetInfo();
}
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ if (!m_framebufferBinding || !m_framebufferBinding->object() || m_framebufferBinding->isIncomplete(false)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return WebGLGetInfo();
}
@@ -1316,6 +1458,8 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned l
WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
WebGLStateRestorer(this, false);
switch (pname) {
case GraphicsContext3D::ACTIVE_TEXTURE:
@@ -1383,10 +1527,6 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
return getUnsignedLongParameter(pname);
case GraphicsContext3D::GREEN_BITS:
return getLongParameter(pname);
- case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
- return getLongParameter(pname);
- case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
- return getLongParameter(pname);
case GraphicsContext3D::LINE_WIDTH:
return getFloatParameter(pname);
case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
@@ -1507,7 +1647,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionC
WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return WebGLGetInfo();
WebGLStateRestorer(this, false);
@@ -1536,6 +1676,8 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, u
String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
if (!validateWebGLObject(program))
return "";
WebGLStateRestorer(this, false);
@@ -1545,10 +1687,48 @@ String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, Exception
WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
if (target != GraphicsContext3D::RENDERBUFFER) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return WebGLGetInfo();
}
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return WebGLGetInfo();
+ }
+
+ if (m_renderbufferBinding->getInternalFormat() == GraphicsContext3D::DEPTH_STENCIL
+ && !m_renderbufferBinding->isValid()) {
+ ASSERT(!m_isDepthStencilSupported);
+ long value = 0;
+ switch (pname) {
+ case GraphicsContext3D::RENDERBUFFER_WIDTH:
+ value = static_cast<long>(m_renderbufferBinding->getWidth());
+ break;
+ case GraphicsContext3D::RENDERBUFFER_HEIGHT:
+ value = static_cast<long>(m_renderbufferBinding->getHeight());
+ break;
+ case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
+ case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
+ value = 0;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
+ value = 24;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
+ value = 8;
+ break;
+ case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
+ return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return WebGLGetInfo();
+ }
+ return WebGLGetInfo(value);
+ }
WebGLStateRestorer(this, false);
int value = 0;
@@ -1564,10 +1744,6 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long targe
m_context->getRenderbufferParameteriv(target, pname, &value);
return WebGLGetInfo(static_cast<long>(value));
case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
- if (!m_renderbufferBinding) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
- return WebGLGetInfo();
- }
return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
default:
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
@@ -1578,7 +1754,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long targe
WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject(shader))
return WebGLGetInfo();
WebGLStateRestorer(this, false);
int value = 0;
@@ -1603,6 +1779,8 @@ WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsi
String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
if (!validateWebGLObject(shader))
return "";
WebGLStateRestorer(this, false);
@@ -1612,6 +1790,8 @@ String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCod
String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return String();
if (!validateWebGLObject(shader))
return "";
WebGLStateRestorer(this, false);
@@ -1621,6 +1801,8 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode
WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
WebGLTexture* tex = validateTextureBinding(target, false);
if (!tex)
return WebGLGetInfo();
@@ -1642,7 +1824,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsign
WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return WebGLGetInfo();
if (!uniformLocation) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -1755,20 +1937,20 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
return WebGLGetInfo(Float32Array::create(value, length));
}
case GraphicsContext3D::INT: {
- int value[16] = {0};
+ int value[4] = {0};
m_context->getUniformiv(objectOrZero(program), location, value);
if (length == 1)
return WebGLGetInfo(static_cast<long>(value[0]));
return WebGLGetInfo(Int32Array::create(value, length));
}
case GraphicsContext3D::BOOL: {
- int value[16] = {0};
+ int value[4] = {0};
m_context->getUniformiv(objectOrZero(program), location, value);
if (length > 1) {
- unsigned char boolValue[16] = {0};
+ bool boolValue[16] = {0};
for (unsigned j = 0; j < length; j++)
boolValue[j] = static_cast<bool>(value[j]);
- return WebGLGetInfo(Uint8Array::create(boolValue, length));
+ return WebGLGetInfo(boolValue, length);
}
return WebGLGetInfo(static_cast<bool>(value[0]));
}
@@ -1786,7 +1968,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return 0;
WebGLStateRestorer(this, false);
long uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
@@ -1798,6 +1980,8 @@ PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGL
WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return WebGLGetInfo();
WebGLStateRestorer(this, false);
if (index >= m_maxVertexAttribs) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -1845,6 +2029,8 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigne
long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname)
{
+ if (isContextLost())
+ return 0;
long result = m_context->getVertexAttribOffset(index, pname);
cleanupAfterGraphicsCall(false);
return result;
@@ -1852,6 +2038,8 @@ long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned
void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
{
+ if (isContextLost())
+ return;
if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return;
@@ -1862,22 +2050,27 @@ void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
{
- if (!buffer)
+ if (!buffer || isContextLost())
return false;
return m_context->isBuffer(buffer->object());
}
+bool WebGLRenderingContext::isContextLost() const
+{
+ return m_contextLost;
+}
+
bool WebGLRenderingContext::isEnabled(unsigned long cap)
{
- if (!validateCapability(cap))
+ if (!validateCapability(cap) || isContextLost())
return false;
return m_context->isEnabled(cap);
}
bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
{
- if (!framebuffer)
+ if (!framebuffer || isContextLost())
return false;
return m_context->isFramebuffer(framebuffer->object());
@@ -1885,7 +2078,7 @@ bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
bool WebGLRenderingContext::isProgram(WebGLProgram* program)
{
- if (!program)
+ if (!program || isContextLost())
return false;
return m_context->isProgram(program->object());
@@ -1893,7 +2086,7 @@ bool WebGLRenderingContext::isProgram(WebGLProgram* program)
bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
{
- if (!renderbuffer)
+ if (!renderbuffer || isContextLost())
return false;
return m_context->isRenderbuffer(renderbuffer->object());
@@ -1901,7 +2094,7 @@ bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
bool WebGLRenderingContext::isShader(WebGLShader* shader)
{
- if (!shader)
+ if (!shader || isContextLost())
return false;
return m_context->isShader(shader->object());
@@ -1909,7 +2102,7 @@ bool WebGLRenderingContext::isShader(WebGLShader* shader)
bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
{
- if (!texture)
+ if (!texture || isContextLost())
return false;
return m_context->isTexture(texture->object());
@@ -1917,6 +2110,8 @@ bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
void WebGLRenderingContext::lineWidth(double width)
{
+ if (isContextLost())
+ return;
m_context->lineWidth((float) width);
cleanupAfterGraphicsCall(false);
}
@@ -1924,7 +2119,7 @@ void WebGLRenderingContext::lineWidth(double width)
void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return;
if (!isGLES2Compliant()) {
if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) {
@@ -1944,6 +2139,8 @@ void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec
void WebGLRenderingContext::pixelStorei(unsigned long pname, long param)
{
+ if (isContextLost())
+ return;
switch (pname) {
case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
m_unpackFlipY = param;
@@ -1970,12 +2167,16 @@ void WebGLRenderingContext::pixelStorei(unsigned long pname, long param)
void WebGLRenderingContext::polygonOffset(double factor, double units)
{
+ if (isContextLost())
+ return;
m_context->polygonOffset((float) factor, (float) units);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels, ExceptionCode& ec)
{
+ if (isContextLost())
+ return;
if (!canvas()->originClean()) {
ec = SECURITY_ERR;
return;
@@ -1994,7 +2195,7 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) {
+ if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
@@ -2004,6 +2205,10 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ return;
+ }
// Calculate array size, taking into consideration of PACK_ALIGNMENT.
unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
unsigned long padding = 0;
@@ -2043,27 +2248,44 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
void WebGLRenderingContext::releaseShaderCompiler()
{
+ if (isContextLost())
+ return;
m_context->releaseShaderCompiler();
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
{
+ if (isContextLost())
+ return;
+ if (target != GraphicsContext3D::RENDERBUFFER) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
switch (internalformat) {
case GraphicsContext3D::DEPTH_COMPONENT16:
case GraphicsContext3D::RGBA4:
case GraphicsContext3D::RGB5_A1:
case GraphicsContext3D::RGB565:
case GraphicsContext3D::STENCIL_INDEX8:
- case GraphicsContext3D::DEPTH_STENCIL:
m_context->renderbufferStorage(target, internalformat, width, height);
- if (m_renderbufferBinding) {
- m_renderbufferBinding->setInternalFormat(internalformat);
- if (m_framebufferBinding)
- m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get());
- }
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ m_renderbufferBinding->setIsValid(true);
cleanupAfterGraphicsCall(false);
break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ if (m_isDepthStencilSupported) {
+ m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
+ cleanupAfterGraphicsCall(false);
+ } else
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->setIsValid(m_isDepthStencilSupported);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ break;
default:
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
}
@@ -2071,12 +2293,16 @@ void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned l
void WebGLRenderingContext::sampleCoverage(double value, bool invert)
{
+ if (isContextLost())
+ return;
m_context->sampleCoverage((float) value, invert);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height)
{
+ if (isContextLost())
+ return;
m_context->scissor(x, y, width, height);
cleanupAfterGraphicsCall(false);
}
@@ -2084,7 +2310,7 @@ void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigne
void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject(shader))
return;
m_context->shaderSource(objectOrZero(shader), string);
cleanupAfterGraphicsCall(false);
@@ -2092,36 +2318,72 @@ void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& stri
void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask)
{
+ if (isContextLost())
+ return;
+ if (!validateStencilFunc(func))
+ return;
+ m_stencilFuncRef = ref;
+ m_stencilFuncMask = mask;
m_context->stencilFunc(func, ref, mask);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
{
+ if (isContextLost())
+ return;
+ if (!validateFace(face) || !validateStencilFunc(func))
+ return;
+ if (face == GraphicsContext3D::FRONT_AND_BACK) {
+ m_stencilFuncRef = ref;
+ m_stencilFuncMask = mask;
+ } else if (m_stencilFuncRef != ref || m_stencilFuncMask != mask) {
+ // for ref value, we generate an error if user specify a different value
+ // for front/back faces even if they clamp to the same value internally.
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
m_context->stencilFuncSeparate(face, func, ref, mask);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::stencilMask(unsigned long mask)
{
+ if (isContextLost())
+ return;
+ m_stencilMask = mask;
m_context->stencilMask(mask);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask)
{
+ if (isContextLost())
+ return;
+ if (!validateFace(face))
+ return;
+ if (face == GraphicsContext3D::FRONT_AND_BACK)
+ m_stencilMask = mask;
+ else if (m_stencilMask != mask) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return;
+ }
m_context->stencilMaskSeparate(face, mask);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
{
+ if (isContextLost())
+ return;
m_context->stencilOp(fail, zfail, zpass);
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
{
+ if (isContextLost())
+ return;
m_context->stencilOpSeparate(face, fail, zfail, zpass);
cleanupAfterGraphicsCall(false);
}
@@ -2146,8 +2408,6 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
m_context->texImage2D(target, level, internalformat, width, height,
border, format, type, pixels);
tex->setLevelInfo(target, level, internalformat, width, height, type);
- if (m_framebufferBinding)
- m_framebufferBinding->onAttachedObjectChange(tex);
cleanupAfterGraphicsCall(false);
}
@@ -2173,7 +2433,7 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
unsigned width, unsigned height, unsigned border,
unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
{
- if (!validateTexFuncData(width, height, format, type, pixels))
+ if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels))
return;
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
@@ -2200,6 +2460,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
Vector<uint8_t> data;
if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -2217,6 +2479,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
if (!image || !image->cachedImage()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -2230,6 +2494,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
if (!canvas || !canvas->buffer()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -2262,6 +2528,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
RefPtr<Image> image = videoFrameToImage(video);
if (!video)
return;
@@ -2270,6 +2538,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
{
+ if (isContextLost())
+ return;
WebGLTexture* tex = validateTextureBinding(target, false);
if (!tex)
return;
@@ -2315,6 +2585,8 @@ void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, u
{
// FIXME: For now we ignore any errors returned
ec = 0;
+ if (isContextLost())
+ return;
if (!validateTexFuncFormatAndType(format, type))
return;
if (!validateTextureBinding(target, true))
@@ -2328,6 +2600,8 @@ void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, u
Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
Vector<uint8_t> data;
if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -2341,7 +2615,7 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
unsigned width, unsigned height,
unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
{
- if (!validateTexFuncData(width, height, format, type, pixels))
+ if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels))
return;
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
@@ -2367,6 +2641,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
Vector<uint8_t> data;
if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -2380,6 +2656,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
if (!image || !image->cachedImage()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -2393,6 +2671,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
if (!canvas || !canvas->buffer()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -2406,6 +2686,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
{
ec = 0;
+ if (isContextLost())
+ return;
RefPtr<Image> image = videoFrameToImage(video);
if (!video)
return;
@@ -2415,7 +2697,7 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2430,7 +2712,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, floa
void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 1))
+ if (isContextLost() || !validateUniformParameters(location, v, 1))
return;
m_context->uniform1fv(location->location(), v->data(), v->length());
@@ -2440,7 +2722,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 1))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 1))
return;
m_context->uniform1fv(location->location(), v, size);
@@ -2450,7 +2732,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, flo
void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2465,7 +2747,7 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 1))
+ if (isContextLost() || !validateUniformParameters(location, v, 1))
return;
m_context->uniform1iv(location->location(), v->data(), v->length());
@@ -2475,7 +2757,7 @@ void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 1))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 1))
return;
m_context->uniform1iv(location->location(), v, size);
@@ -2485,7 +2767,7 @@ void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2500,7 +2782,7 @@ void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, floa
void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 2))
+ if (isContextLost() || !validateUniformParameters(location, v, 2))
return;
m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
@@ -2510,7 +2792,7 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 2))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 2))
return;
m_context->uniform2fv(location->location(), v, size / 2);
@@ -2520,7 +2802,7 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, flo
void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2535,7 +2817,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 2))
+ if (isContextLost() || !validateUniformParameters(location, v, 2))
return;
m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
@@ -2545,7 +2827,7 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 2))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 2))
return;
m_context->uniform2iv(location->location(), v, size / 2);
@@ -2555,7 +2837,7 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2570,7 +2852,7 @@ void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, floa
void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 3))
+ if (isContextLost() || !validateUniformParameters(location, v, 3))
return;
m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
@@ -2580,7 +2862,7 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 3))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 3))
return;
m_context->uniform3fv(location->location(), v, size / 3);
@@ -2590,7 +2872,7 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, flo
void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2605,7 +2887,7 @@ void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 3))
+ if (isContextLost() || !validateUniformParameters(location, v, 3))
return;
m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
@@ -2615,7 +2897,7 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 3))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 3))
return;
m_context->uniform3iv(location->location(), v, size / 3);
@@ -2625,7 +2907,7 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2640,7 +2922,7 @@ void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, floa
void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 4))
+ if (isContextLost() || !validateUniformParameters(location, v, 4))
return;
m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
@@ -2650,7 +2932,7 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 4))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 4))
return;
m_context->uniform4fv(location->location(), v, size / 4);
@@ -2660,7 +2942,7 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, flo
void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!location)
+ if (isContextLost() || !location)
return;
if (location->program() != m_currentProgram) {
@@ -2675,7 +2957,7 @@ void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, 4))
+ if (isContextLost() || !validateUniformParameters(location, v, 4))
return;
m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
@@ -2685,7 +2967,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformParameters(location, v, size, 4))
+ if (isContextLost() || !validateUniformParameters(location, v, size, 4))
return;
m_context->uniform4iv(location->location(), v, size / 4);
@@ -2695,7 +2977,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int
void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformMatrixParameters(location, transpose, v, 4))
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 4))
return;
m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
cleanupAfterGraphicsCall(false);
@@ -2704,7 +2986,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformMatrixParameters(location, transpose, v, size, 4))
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 4))
return;
m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
cleanupAfterGraphicsCall(false);
@@ -2713,7 +2995,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformMatrixParameters(location, transpose, v, 9))
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 9))
return;
m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
cleanupAfterGraphicsCall(false);
@@ -2722,7 +3004,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformMatrixParameters(location, transpose, v, size, 9))
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 9))
return;
m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
cleanupAfterGraphicsCall(false);
@@ -2731,7 +3013,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformMatrixParameters(location, transpose, v, 16))
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 16))
return;
m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
cleanupAfterGraphicsCall(false);
@@ -2740,7 +3022,7 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateUniformMatrixParameters(location, transpose, v, size, 16))
+ if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 16))
return;
m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
cleanupAfterGraphicsCall(false);
@@ -2749,6 +3031,8 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (program && program->context() != this) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
@@ -2772,7 +3056,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (!validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject(program))
return;
m_context->validateProgram(objectOrZero(program));
cleanupAfterGraphicsCall(false);
@@ -2841,11 +3125,13 @@ void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int s
void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, long offset, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
+ if (isContextLost())
+ return;
if (index >= m_maxVertexAttribs) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- if (size < 1 || size > 4 || stride < 0 || offset < 0) {
+ if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
@@ -2885,6 +3171,8 @@ void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size,
void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height)
{
+ if (isContextLost())
+ return;
if (isnan(x))
x = 0;
if (isnan(y))
@@ -2897,6 +3185,44 @@ void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsign
cleanupAfterGraphicsCall(false);
}
+void WebGLRenderingContext::loseContext()
+{
+ if (isContextLost())
+ return;
+
+ m_contextLost = true;
+
+ detachAndRemoveAllObjects();
+
+ // There is no direct way to clear errors from a GL implementation and
+ // looping until getError() becomes NO_ERROR might cause an infinite loop if
+ // the driver or context implementation had a bug. So, loop a reasonably
+ // large number of times to clear any existing errors.
+ for (int i = 0; i < 100; ++i) {
+ if (m_context->getError() == GraphicsContext3D::NO_ERROR)
+ break;
+ }
+ m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
+
+ canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, ""));
+}
+
+void WebGLRenderingContext::restoreContext()
+{
+ if (!isContextLost())
+ return;
+
+ // The rendering context is not restored if there is no handler for
+ // the context restored event.
+ if (!canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent))
+ return;
+
+ m_contextLost = false;
+ initializeNewContext();
+
+ canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, ""));
+}
+
void WebGLRenderingContext::removeObject(WebGLObject* object)
{
m_canvasObjects.remove(object);
@@ -2904,6 +3230,7 @@ void WebGLRenderingContext::removeObject(WebGLObject* object)
void WebGLRenderingContext::addObject(WebGLObject* object)
{
+ ASSERT(!isContextLost());
removeObject(object);
m_canvasObjects.add(object);
}
@@ -3355,6 +3682,37 @@ bool WebGLRenderingContext::validateDrawMode(unsigned long mode)
}
}
+bool WebGLRenderingContext::validateFace(unsigned long face)
+{
+ switch (face) {
+ case GraphicsContext3D::FRONT:
+ case GraphicsContext3D::BACK:
+ case GraphicsContext3D::FRONT_AND_BACK:
+ return true;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
+bool WebGLRenderingContext::validateStencilFunc(unsigned long func)
+{
+ switch (func) {
+ case GraphicsContext3D::NEVER:
+ case GraphicsContext3D::LESS:
+ case GraphicsContext3D::LEQUAL:
+ case GraphicsContext3D::GREATER:
+ case GraphicsContext3D::GEQUAL:
+ case GraphicsContext3D::EQUAL:
+ case GraphicsContext3D::NOTEQUAL:
+ case GraphicsContext3D::ALWAYS:
+ return true;
+ default:
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return false;
+ }
+}
+
void WebGLRenderingContext::printWarningToConsole(const String& message)
{
canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel,
@@ -3393,6 +3751,18 @@ bool WebGLRenderingContext::validateBlendEquation(unsigned long mode)
}
}
+bool WebGLRenderingContext::validateBlendFuncFactors(unsigned long src, unsigned long dst)
+{
+ if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
+ && (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))
+ || ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
+ && (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ return false;
+ }
+ return true;
+}
+
bool WebGLRenderingContext::validateCapability(unsigned long cap)
{
switch (cap) {
@@ -3497,6 +3867,8 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(unsigned long t
void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3)
{
+ if (isContextLost())
+ return;
if (index >= m_maxVertexAttribs) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -3529,6 +3901,8 @@ void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedS
void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array* v, int expectedSize)
{
+ if (isContextLost())
+ return;
if (!v) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
@@ -3538,6 +3912,8 @@ void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array
void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, float* v, int size, int expectedSize)
{
+ if (isContextLost())
+ return;
if (!v) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index ce66f6a..5f66248 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -176,6 +176,7 @@ public:
void hint(unsigned long target, unsigned long mode);
bool isBuffer(WebGLBuffer*);
+ bool isContextLost() const;
bool isEnabled(unsigned long cap);
bool isFramebuffer(WebGLFramebuffer*);
bool isProgram(WebGLProgram*);
@@ -277,6 +278,9 @@ public:
void viewport(long x, long y, unsigned long width, unsigned long height);
+ void loseContext();
+ void restoreContext();
+
GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
#if USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const { return m_context->platformLayer(); }
@@ -292,6 +296,7 @@ public:
friend class WebGLObject;
WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>);
+ void initializeNewContext();
void addObject(WebGLObject*);
void detachAndRemoveAllObjects();
@@ -333,8 +338,6 @@ public:
RefPtr<GraphicsContext3D> m_context;
bool m_needsUpdate;
bool m_markedCanvasDirty;
- // FIXME: I think this is broken -- it does not increment any
- // reference counts, so may refer to destroyed objects.
HashSet<RefPtr<WebGLObject> > m_canvasObjects;
// List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
@@ -417,10 +420,16 @@ public:
int m_packAlignment;
int m_unpackAlignment;
- unsigned long m_implementationColorReadFormat;
- unsigned long m_implementationColorReadType;
bool m_unpackFlipY;
bool m_unpackPremultiplyAlpha;
+ bool m_contextLost;
+
+ long m_stencilBits;
+ unsigned long m_stencilMask;
+ long m_stencilFuncRef; // Note that this is the user specified value, not the internal clamped value.
+ unsigned long m_stencilFuncMask;
+
+ bool m_isDepthStencilSupported;
// Helpers for getParameter and others
WebGLGetInfo getBooleanParameter(unsigned long pname);
@@ -481,6 +490,12 @@ public:
// Helper function to validate mode for draw{Arrays/Elements}.
bool validateDrawMode(unsigned long);
+ // Helper function to validate face.
+ bool validateFace(unsigned long);
+
+ // Helper function to validate stencil func.
+ bool validateStencilFunc(unsigned long);
+
// Helper function for texParameterf and texParameteri.
void texParameter(unsigned long target, unsigned long pname, float parami, int paramf, bool isFloat);
@@ -495,6 +510,9 @@ public:
// Helper function to validate blend equation mode.
bool validateBlendEquation(unsigned long);
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(unsigned long src, unsigned long dst);
+
// Helper function to validate a GL capability.
bool validateCapability(unsigned long);
diff --git a/WebCore/html/canvas/WebGLRenderingContext.idl b/WebCore/html/canvas/WebGLRenderingContext.idl
index f76646d..4d41b78 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -392,10 +392,6 @@ module html {
const unsigned int VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
const unsigned int VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
- /* Read Format */
- const unsigned int IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
- const unsigned int IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
-
/* Shader Source */
const unsigned int COMPILE_STATUS = 0x8B81;
const unsigned int INFO_LOG_LENGTH = 0x8B84;
@@ -463,6 +459,7 @@ module html {
/* WebGL-specific enums */
const unsigned int UNPACK_FLIP_Y_WEBGL = 0x9240;
const unsigned int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const unsigned int CONTEXT_LOST_WEBGL = 0x9242;
[StrictTypeChecking] void activeTexture(in unsigned long texture) raises(DOMException);
[StrictTypeChecking] void attachShader(in WebGLProgram program, in WebGLShader shader) raises(DOMException);
@@ -551,18 +548,18 @@ module html {
[StrictTypeChecking, Custom] void getParameter();
// any getProgramParameter(in WebGLProgram program, in unsigned long pname) raises(DOMException);
[StrictTypeChecking, Custom] void getProgramParameter();
- [StrictTypeChecking] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException);
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getProgramInfoLog(in WebGLProgram program) raises(DOMException);
// any getRenderbufferParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
[StrictTypeChecking, Custom] void getRenderbufferParameter();
// any getShaderParameter(in WebGLShader shader, in unsigned long pname) raises(DOMException);
[StrictTypeChecking, Custom] void getShaderParameter() raises(DOMException);
- [StrictTypeChecking] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderInfoLog(in WebGLShader shader) raises(DOMException);
// TBD
// void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
- [StrictTypeChecking] DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
+ [StrictTypeChecking, ConvertNullStringTo=Null] DOMString getShaderSource(in WebGLShader shader) raises(DOMException);
// any getTexParameter(in unsigned long target, in unsigned long pname) raises(DOMException);
[StrictTypeChecking, Custom] void getTexParameter();
@@ -579,6 +576,7 @@ module html {
[StrictTypeChecking] void hint(in unsigned long target, in unsigned long mode);
[StrictTypeChecking] boolean isBuffer(in WebGLBuffer buffer);
+ [StrictTypeChecking] boolean isContextLost();
[StrictTypeChecking] boolean isEnabled(in unsigned long cap);
[StrictTypeChecking] boolean isFramebuffer(in WebGLFramebuffer framebuffer);
[StrictTypeChecking] boolean isProgram(in WebGLProgram program);
diff --git a/WebCore/html/parser/HTMLTreeBuilder.cpp b/WebCore/html/parser/HTMLTreeBuilder.cpp
index 310ff60..6134607 100644
--- a/WebCore/html/parser/HTMLTreeBuilder.cpp
+++ b/WebCore/html/parser/HTMLTreeBuilder.cpp
@@ -2295,7 +2295,8 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
while (1) {
if (nodeRecord->element()->hasLocalName(token.name())) {
m_tree.openElements()->popUntilPopped(nodeRecord->element());
- break;
+ resetForeignInsertionMode();
+ return;
}
nodeRecord = nodeRecord->next();
if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI)
@@ -2580,7 +2581,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
case AfterBodyMode:
case AfterAfterBodyMode:
ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
- return;
+ break;
case InHeadNoscriptMode:
ASSERT(insertionMode() == InHeadNoscriptMode);
defaultForInHeadNoscript();
@@ -2602,11 +2603,11 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
case InColumnGroupMode:
if (m_tree.currentElement() == m_tree.openElements()->htmlElement()) {
ASSERT(isParsingFragment());
- return;
+ return; // FIXME: Should we break here instead of returning?
}
if (!processColgroupEndTagForInColumnGroup()) {
ASSERT(isParsingFragment());
- return;
+ return; // FIXME: Should we break here instead of returning?
}
prepareToReprocessToken();
processEndOfFile(token);