Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 if (!desiredSize.isEmpty()) { | 215 if (!desiredSize.isEmpty()) { |
| 216 forciblyEvictedContexts().remove(0); | 216 forciblyEvictedContexts().remove(0); |
| 217 evictedContext->forceRestoreContext(); | 217 evictedContext->forceRestoreContext(); |
| 218 } | 218 } |
| 219 break; | 219 break; |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 | 222 |
| 223 namespace { | 223 namespace { |
| 224 | 224 |
| 225 // ScopedDrawingBufferBinder is used for ReadPixels/CopyTexImage2D/CopySubImage2 D to read from | |
| 226 // a multisampled DrawingBuffer. In this situation, we need to blit to a single sampled buffer | |
| 227 // for reading, during which the bindings could be changed and need to be recove red. | |
| 228 class ScopedDrawingBufferBinder { | |
| 229 STACK_ALLOCATED(); | |
| 230 public: | |
| 231 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* fr amebufferBinding) | |
| 232 : m_drawingBuffer(drawingBuffer) | |
| 233 , m_readFramebufferBinding(framebufferBinding) | |
| 234 { | |
| 235 // Commit DrawingBuffer if needed (e.g., for multisampling) | |
| 236 if (!m_readFramebufferBinding && m_drawingBuffer) | |
| 237 m_drawingBuffer->commit(); | |
| 238 } | |
| 239 | |
| 240 ~ScopedDrawingBufferBinder() | |
| 241 { | |
| 242 // Restore DrawingBuffer if needed | |
| 243 if (!m_readFramebufferBinding && m_drawingBuffer) | |
| 244 m_drawingBuffer->restoreFramebufferBindings(); | |
| 245 } | |
| 246 | |
| 247 private: | |
| 248 DrawingBuffer* m_drawingBuffer; | |
| 249 Member<WebGLFramebuffer> m_readFramebufferBinding; | |
| 250 }; | |
| 251 | |
| 252 GLint clamp(GLint value, GLint min, GLint max) | 225 GLint clamp(GLint value, GLint min, GLint max) |
| 253 { | 226 { |
| 254 if (value < min) | 227 if (value < min) |
| 255 value = min; | 228 value = min; |
| 256 if (value > max) | 229 if (value > max) |
| 257 value = max; | 230 value = max; |
| 258 return value; | 231 return value; |
| 259 } | 232 } |
| 260 | 233 |
| 261 // Return true if a character belongs to the ASCII subset as defined in | 234 // Return true if a character belongs to the ASCII subset as defined in |
| (...skipping 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1889 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); | 1862 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
| 1890 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei ght, border); | 1863 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei ght, border); |
| 1891 // FIXME: if the framebuffer is not complete, none of the below should be ex ecuted. | 1864 // FIXME: if the framebuffer is not complete, none of the below should be ex ecuted. |
| 1892 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN ED_BYTE); | 1865 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN ED_BYTE); |
| 1893 } | 1866 } |
| 1894 | 1867 |
| 1895 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) | 1868 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) |
| 1896 { | 1869 { |
| 1897 if (isContextLost()) | 1870 if (isContextLost()) |
| 1898 return; | 1871 return; |
| 1899 if (!validateTexFuncLevel("copyTexSubImage2D", target, level)) | 1872 if (!validateCopyTexSubImage("copyTexSubImage2D", target, level, xoffset, yo ffset, 0, x, y, width, height)) |
| 1900 return; | 1873 return; |
| 1901 WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true ); | |
| 1902 if (!tex) | |
| 1903 return; | |
| 1904 if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("c opyTexSubImage2D", width, height)) | |
| 1905 return; | |
| 1906 // Before checking if it is in the range, check if overflow happens first. | |
| 1907 Checked<GLint, RecordOverflow> maxX = xoffset; | |
| 1908 maxX += width; | |
| 1909 Checked<GLint, RecordOverflow> maxY = yoffset; | |
| 1910 maxY += height; | |
| 1911 if (maxX.hasOverflowed() || maxY.hasOverflowed()) { | |
| 1912 synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions "); | |
| 1913 return; | |
| 1914 } | |
| 1915 if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > te x->getHeight(target, level)) { | |
| 1916 synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range"); | |
| 1917 return; | |
| 1918 } | |
| 1919 GLenum internalformat = tex->getInternalFormat(target, level); | |
| 1920 if (!validateSettableTexFormat("copyTexSubImage2D", internalformat)) | |
| 1921 return; | |
| 1922 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) { | |
| 1923 synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffe r is incompatible format"); | |
| 1924 return; | |
| 1925 } | |
| 1926 WebGLFramebuffer* readFramebufferBinding = nullptr; | 1874 WebGLFramebuffer* readFramebufferBinding = nullptr; |
| 1927 if (!validateReadBufferAndGetInfo("copyTexSubImage2D", readFramebufferBindin g, nullptr, nullptr)) | 1875 if (!validateReadBufferAndGetInfo("copyTexSubImage2D", readFramebufferBindin g, nullptr, nullptr)) |
| 1928 return; | 1876 return; |
| 1929 clearIfComposited(); | 1877 clearIfComposited(); |
| 1930 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); | 1878 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
| 1931 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height); | 1879 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height); |
| 1932 } | 1880 } |
| 1933 | 1881 |
| 1934 WebGLBuffer* WebGLRenderingContextBase::createBuffer() | 1882 WebGLBuffer* WebGLRenderingContextBase::createBuffer() |
| 1935 { | 1883 { |
| (...skipping 3445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5381 bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string) | 5329 bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string) |
| 5382 { | 5330 { |
| 5383 const unsigned maxWebGLLocationLength = getMaxWebGLLocationLength(); | 5331 const unsigned maxWebGLLocationLength = getMaxWebGLLocationLength(); |
| 5384 if (string.length() > maxWebGLLocationLength) { | 5332 if (string.length() > maxWebGLLocationLength) { |
| 5385 synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256 "); | 5333 synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256 "); |
| 5386 return false; | 5334 return false; |
| 5387 } | 5335 } |
| 5388 return true; | 5336 return true; |
| 5389 } | 5337 } |
| 5390 | 5338 |
| 5391 bool WebGLRenderingContextBase::validateSize(const char* functionName, GLint x, GLint y) | 5339 bool WebGLRenderingContextBase::validateSize(const char* functionName, GLint x, GLint y, GLint z) |
| 5392 { | 5340 { |
| 5393 if (x < 0 || y < 0) { | 5341 if (x < 0 || y < 0 || z < 0) { |
| 5394 synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0"); | 5342 synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0"); |
| 5395 return false; | 5343 return false; |
| 5396 } | 5344 } |
| 5397 return true; | 5345 return true; |
| 5398 } | 5346 } |
| 5399 | 5347 |
| 5400 bool WebGLRenderingContextBase::validateString(const char* functionName, const S tring& string) | 5348 bool WebGLRenderingContextBase::validateString(const char* functionName, const S tring& string) |
| 5401 { | 5349 { |
| 5402 for (size_t i = 0; i < string.length(); ++i) { | 5350 for (size_t i = 0; i < string.length(); ++i) { |
| 5403 if (!validateCharacter(string[i])) { | 5351 if (!validateCharacter(string[i])) { |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5663 synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBuff erView not big enough for request with UNPACK_ALIGNMENT > 1"); | 5611 synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBuff erView not big enough for request with UNPACK_ALIGNMENT > 1"); |
| 5664 return false; | 5612 return false; |
| 5665 } | 5613 } |
| 5666 } | 5614 } |
| 5667 synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView n ot big enough for request"); | 5615 synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView n ot big enough for request"); |
| 5668 return false; | 5616 return false; |
| 5669 } | 5617 } |
| 5670 return true; | 5618 return true; |
| 5671 } | 5619 } |
| 5672 | 5620 |
| 5621 bool WebGLRenderingContextBase::validateCopyTexSubImage(const char* functionName , GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) | |
| 5622 { | |
| 5623 if (!validateTexFuncLevel(functionName, target, level)) | |
| 5624 return false; | |
| 5625 WebGLTexture* tex = validateTextureBinding(functionName, target, true); | |
| 5626 if (!tex) | |
| 5627 return false; | |
| 5628 if (!validateSize(functionName, xoffset, yoffset, zoffset) || !validateSize( functionName, width, height)) | |
| 5629 return false; | |
| 5630 // Before checking if it is in the range, check if overflow happens first. | |
| 5631 Checked<GLint, RecordOverflow> maxX = xoffset; | |
| 5632 maxX += width; | |
| 5633 Checked<GLint, RecordOverflow> maxY = yoffset; | |
| 5634 maxY += height; | |
| 5635 if (maxX.hasOverflowed() || maxY.hasOverflowed()) { | |
| 5636 synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions"); | |
| 5637 return false; | |
| 5638 } | |
| 5639 if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > te x->getHeight(target, level) || zoffset >= tex->getDepth(target, level)) { | |
| 5640 synthesizeGLError(GL_INVALID_VALUE, functionName, "rectangle out of rang e"); | |
| 5641 return false; | |
| 5642 } | |
| 5643 GLenum internalformat = tex->getInternalFormat(target, level); | |
| 5644 if (!validateSettableTexFormat(functionName, internalformat)) | |
| 5645 return false; | |
| 5646 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) { | |
|
Zhenyao Mo
2015/08/26 23:44:38
I don't think boundFramebufferColorFormat() does t
Ken Russell (switch to Gerrit)
2015/08/27 02:01:03
Agreed, boundFramebufferColorFormat looks like it
| |
| 5647 synthesizeGLError(GL_INVALID_OPERATION, functionName, "framebuffer is in compatible format"); | |
| 5648 return false; | |
| 5649 } | |
| 5650 | |
| 5651 return true; | |
| 5652 } | |
| 5653 | |
| 5673 bool WebGLRenderingContextBase::validateCompressedTexFormat(GLenum format) | 5654 bool WebGLRenderingContextBase::validateCompressedTexFormat(GLenum format) |
| 5674 { | 5655 { |
| 5675 return m_compressedTextureFormats.contains(format); | 5656 return m_compressedTextureFormats.contains(format); |
| 5676 } | 5657 } |
| 5677 | 5658 |
| 5678 bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functi onName, GLsizei width, GLsizei height, GLenum format, DOMArrayBufferView* pixels ) | 5659 bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functi onName, GLsizei width, GLsizei height, GLenum format, DOMArrayBufferView* pixels ) |
| 5679 { | 5660 { |
| 5680 if (!pixels) { | 5661 if (!pixels) { |
| 5681 synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels"); | 5662 synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels"); |
| 5682 return false; | 5663 return false; |
| (...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6627 | 6608 |
| 6628 return totalBytesPerPixel; | 6609 return totalBytesPerPixel; |
| 6629 } | 6610 } |
| 6630 | 6611 |
| 6631 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const | 6612 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const |
| 6632 { | 6613 { |
| 6633 return m_drawingBuffer.get(); | 6614 return m_drawingBuffer.get(); |
| 6634 } | 6615 } |
| 6635 | 6616 |
| 6636 } // namespace blink | 6617 } // namespace blink |
| OLD | NEW |