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 |