| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2010, Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #ifndef SKY_ENGINE_PLATFORM_GRAPHICS_GPU_DRAWINGBUFFER_H_ | |
| 32 #define SKY_ENGINE_PLATFORM_GRAPHICS_GPU_DRAWINGBUFFER_H_ | |
| 33 | |
| 34 #include "sky/engine/platform/PlatformExport.h" | |
| 35 #include "sky/engine/platform/geometry/IntSize.h" | |
| 36 #include "sky/engine/platform/graphics/GraphicsTypes3D.h" | |
| 37 #include "sky/engine/platform/graphics/gpu/WebGLImageConversion.h" | |
| 38 #include "sky/engine/public/platform/WebExternalTextureLayerClient.h" | |
| 39 #include "sky/engine/public/platform/WebExternalTextureMailbox.h" | |
| 40 #include "sky/engine/public/platform/WebGraphicsContext3D.h" | |
| 41 #include "sky/engine/wtf/Deque.h" | |
| 42 #include "sky/engine/wtf/Noncopyable.h" | |
| 43 #include "sky/engine/wtf/OwnPtr.h" | |
| 44 #include "sky/engine/wtf/PassOwnPtr.h" | |
| 45 #include "third_party/khronos/GLES2/gl2.h" | |
| 46 #include "third_party/khronos/GLES2/gl2ext.h" | |
| 47 #include "third_party/skia/include/core/SkBitmap.h" | |
| 48 | |
| 49 namespace blink { | |
| 50 | |
| 51 class Extensions3DUtil; | |
| 52 class ImageBuffer; | |
| 53 class WebExternalBitmap; | |
| 54 class WebExternalTextureLayer; | |
| 55 class WebGraphicsContext3D; | |
| 56 class WebLayer; | |
| 57 | |
| 58 // Abstract interface to allow basic context eviction management | |
| 59 class PLATFORM_EXPORT ContextEvictionManager : public RefCounted<ContextEviction
Manager> { | |
| 60 public: | |
| 61 virtual ~ContextEvictionManager() {}; | |
| 62 | |
| 63 virtual void forciblyLoseOldestContext(const String& reason) = 0; | |
| 64 virtual IntSize oldestContextSize() = 0; | |
| 65 }; | |
| 66 | |
| 67 // Manages a rendering target (framebuffer + attachment) for a canvas. Can publ
ish its rendering | |
| 68 // results to a WebLayer for compositing. | |
| 69 class PLATFORM_EXPORT DrawingBuffer : public RefCounted<DrawingBuffer>, public W
ebExternalTextureLayerClient { | |
| 70 // If we used CHROMIUM_image as the backing storage for our buffers, | |
| 71 // we need to know the mapping from texture id to image. | |
| 72 struct TextureInfo { | |
| 73 Platform3DObject textureId; | |
| 74 WGC3Duint imageId; | |
| 75 | |
| 76 TextureInfo() | |
| 77 : textureId(0) | |
| 78 , imageId(0) | |
| 79 { | |
| 80 } | |
| 81 }; | |
| 82 | |
| 83 struct MailboxInfo : public RefCounted<MailboxInfo> { | |
| 84 WebExternalTextureMailbox mailbox; | |
| 85 TextureInfo textureInfo; | |
| 86 IntSize size; | |
| 87 // This keeps the parent drawing buffer alive as long as the compositor
is | |
| 88 // referring to one of the mailboxes DrawingBuffer produced. The parent
drawing buffer is | |
| 89 // cleared when the compositor returns the mailbox. See mailboxReleased(
). | |
| 90 RefPtr<DrawingBuffer> m_parentDrawingBuffer; | |
| 91 }; | |
| 92 public: | |
| 93 enum PreserveDrawingBuffer { | |
| 94 Preserve, | |
| 95 Discard | |
| 96 }; | |
| 97 | |
| 98 static PassRefPtr<DrawingBuffer> create(PassOwnPtr<WebGraphicsContext3D>, co
nst IntSize&, PreserveDrawingBuffer, WebGraphicsContext3D::Attributes requestedA
ttributes, PassRefPtr<ContextEvictionManager>); | |
| 99 | |
| 100 virtual ~DrawingBuffer(); | |
| 101 | |
| 102 // Destruction will be completed after all mailboxes are released. | |
| 103 void beginDestruction(); | |
| 104 | |
| 105 // Issues a glClear() on all framebuffers associated with this DrawingBuffer
. The caller is responsible for | |
| 106 // making the context current and setting the clear values and masks. Modifi
es the framebuffer binding. | |
| 107 void clearFramebuffers(GLbitfield clearMask); | |
| 108 | |
| 109 // Given the desired buffer size, provides the largest dimensions that will
fit in the pixel budget. | |
| 110 static IntSize adjustSize(const IntSize& desiredSize, const IntSize& curSize
, int maxTextureSize); | |
| 111 bool reset(const IntSize&); | |
| 112 void bind(); | |
| 113 IntSize size() const { return m_size; } | |
| 114 | |
| 115 // Copies the multisample color buffer to the normal color buffer and leaves
m_fbo bound. | |
| 116 void commit(long x = 0, long y = 0, long width = -1, long height = -1); | |
| 117 | |
| 118 // commit should copy the full multisample buffer, and not respect the | |
| 119 // current scissor bounds. Track the state of the scissor test so that it | |
| 120 // can be disabled during calls to commit. | |
| 121 void setScissorEnabled(bool scissorEnabled) { m_scissorEnabled = scissorEnab
led; } | |
| 122 | |
| 123 // The DrawingBuffer needs to track the texture bound to texture unit 0. | |
| 124 // The bound texture is tracked to avoid costly queries during rendering. | |
| 125 void setTexture2DBinding(Platform3DObject texture) { m_texture2DBinding = te
xture; } | |
| 126 | |
| 127 // The DrawingBuffer needs to track the currently bound framebuffer so it | |
| 128 // restore the binding when needed. | |
| 129 void setFramebufferBinding(Platform3DObject fbo) { m_framebufferBinding = fb
o; } | |
| 130 | |
| 131 // Track the currently active texture unit. Texture unit 0 is used as host f
or a scratch | |
| 132 // texture. | |
| 133 void setActiveTextureUnit(GLint textureUnit) { m_activeTextureUnit = texture
Unit; } | |
| 134 | |
| 135 bool multisample() const; | |
| 136 | |
| 137 Platform3DObject framebuffer() const; | |
| 138 | |
| 139 void markContentsChanged(); | |
| 140 void markLayerComposited(); | |
| 141 bool layerComposited() const; | |
| 142 void setIsHidden(bool); | |
| 143 | |
| 144 WebLayer* platformLayer(); | |
| 145 void paintCompositedResultsToCanvas(ImageBuffer*); | |
| 146 | |
| 147 WebGraphicsContext3D* context(); | |
| 148 | |
| 149 // Returns the actual context attributes for this drawing buffer which may d
iffer from the | |
| 150 // requested context attributes due to implementation limits. | |
| 151 WebGraphicsContext3D::Attributes getActualAttributes() const { return m_actu
alAttributes; } | |
| 152 | |
| 153 // WebExternalTextureLayerClient implementation. | |
| 154 virtual bool prepareMailbox(WebExternalTextureMailbox*, WebExternalBitmap*)
override; | |
| 155 virtual void mailboxReleased(const WebExternalTextureMailbox&, bool lostReso
urce = false) override; | |
| 156 | |
| 157 // Destroys the TEXTURE_2D binding for the owned context | |
| 158 bool copyToPlatformTexture(WebGraphicsContext3D*, Platform3DObject texture,
GLenum internalFormat, | |
| 159 GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, bool fr
omFrontBuffer = false); | |
| 160 | |
| 161 void setPackAlignment(GLint param); | |
| 162 | |
| 163 void paintRenderingResultsToCanvas(ImageBuffer*); | |
| 164 PassRefPtr<Uint8ClampedArray> paintRenderingResultsToImageData(int&, int&); | |
| 165 | |
| 166 protected: // For unittests | |
| 167 DrawingBuffer( | |
| 168 PassOwnPtr<WebGraphicsContext3D>, | |
| 169 PassOwnPtr<Extensions3DUtil>, | |
| 170 bool multisampleExtensionSupported, | |
| 171 bool packedDepthStencilExtensionSupported, | |
| 172 PreserveDrawingBuffer, | |
| 173 WebGraphicsContext3D::Attributes requestedAttributes, | |
| 174 PassRefPtr<ContextEvictionManager>); | |
| 175 | |
| 176 bool initialize(const IntSize&); | |
| 177 | |
| 178 private: | |
| 179 void mailboxReleasedWithoutRecycling(const WebExternalTextureMailbox&); | |
| 180 | |
| 181 unsigned createColorTexture(); | |
| 182 // Create the depth/stencil and multisample buffers, if needed. | |
| 183 void createSecondaryBuffers(); | |
| 184 bool resizeFramebuffer(const IntSize&); | |
| 185 bool resizeMultisampleFramebuffer(const IntSize&); | |
| 186 void resizeDepthStencil(const IntSize&); | |
| 187 | |
| 188 // Bind to the m_framebufferBinding if it's not 0. | |
| 189 void restoreFramebufferBinding(); | |
| 190 | |
| 191 void clearPlatformLayer(); | |
| 192 | |
| 193 PassRefPtr<MailboxInfo> recycledMailbox(); | |
| 194 PassRefPtr<MailboxInfo> createNewMailbox(const TextureInfo&); | |
| 195 void deleteMailbox(const WebExternalTextureMailbox&); | |
| 196 void freeRecycledMailboxes(); | |
| 197 | |
| 198 // Updates the current size of the buffer, ensuring that s_currentResourceUs
ePixels is updated. | |
| 199 void setSize(const IntSize& size); | |
| 200 | |
| 201 // Calculates the difference in pixels between the current buffer size and t
he proposed size. | |
| 202 static int pixelDelta(const IntSize& newSize, const IntSize& curSize); | |
| 203 | |
| 204 // Given the desired buffer size, provides the largest dimensions that will
fit in the pixel budget | |
| 205 // Returns true if the buffer will only fit if the oldest WebGL context is f
orcibly lost | |
| 206 IntSize adjustSizeWithContextEviction(const IntSize&, bool& evictContext); | |
| 207 | |
| 208 void paintFramebufferToCanvas(int framebuffer, int width, int height, bool p
remultiplyAlpha, ImageBuffer*); | |
| 209 | |
| 210 // This is the order of bytes to use when doing a readback. | |
| 211 enum ReadbackOrder { | |
| 212 ReadbackRGBA, | |
| 213 ReadbackSkia | |
| 214 }; | |
| 215 | |
| 216 // Helper function which does a readback from the currently-bound | |
| 217 // framebuffer into a buffer of a certain size with 4-byte pixels. | |
| 218 void readBackFramebuffer(unsigned char* pixels, int width, int height, Readb
ackOrder, WebGLImageConversion::AlphaOp); | |
| 219 | |
| 220 // Helper function to flip a bitmap vertically. | |
| 221 void flipVertically(uint8_t* data, int width, int height); | |
| 222 | |
| 223 // Helper to texImage2D with pixel==0 case: pixels are initialized to 0. | |
| 224 // By default, alignment is 4, the OpenGL default setting. | |
| 225 void texImage2DResourceSafe(GLenum target, GLint level, GLenum internalforma
t, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLin
t alignment = 4); | |
| 226 // Allocate buffer storage to be sent to compositor using either texImage2D
or CHROMIUM_image based on available support. | |
| 227 void allocateTextureMemory(TextureInfo*, const IntSize&); | |
| 228 void deleteChromiumImageForTexture(TextureInfo*); | |
| 229 | |
| 230 PreserveDrawingBuffer m_preserveDrawingBuffer; | |
| 231 bool m_scissorEnabled; | |
| 232 Platform3DObject m_texture2DBinding; | |
| 233 Platform3DObject m_framebufferBinding; | |
| 234 GLenum m_activeTextureUnit; | |
| 235 | |
| 236 OwnPtr<WebGraphicsContext3D> m_context; | |
| 237 OwnPtr<Extensions3DUtil> m_extensionsUtil; | |
| 238 IntSize m_size; | |
| 239 WebGraphicsContext3D::Attributes m_requestedAttributes; | |
| 240 bool m_multisampleExtensionSupported; | |
| 241 bool m_packedDepthStencilExtensionSupported; | |
| 242 Platform3DObject m_fbo; | |
| 243 // DrawingBuffer's output is double-buffered. m_colorBuffer is the back buff
er. | |
| 244 TextureInfo m_colorBuffer; | |
| 245 TextureInfo m_frontColorBuffer; | |
| 246 | |
| 247 // This is used when we have OES_packed_depth_stencil. | |
| 248 Platform3DObject m_depthStencilBuffer; | |
| 249 | |
| 250 // These are used when we don't. | |
| 251 Platform3DObject m_depthBuffer; | |
| 252 Platform3DObject m_stencilBuffer; | |
| 253 | |
| 254 // For multisampling. | |
| 255 Platform3DObject m_multisampleFBO; | |
| 256 Platform3DObject m_multisampleColorBuffer; | |
| 257 | |
| 258 // True if our contents have been modified since the last presentation of th
is buffer. | |
| 259 bool m_contentsChanged; | |
| 260 | |
| 261 // True if commit() has been called since the last time markContentsChanged(
) had been called. | |
| 262 bool m_contentsChangeCommitted; | |
| 263 bool m_layerComposited; | |
| 264 | |
| 265 enum MultisampleMode { | |
| 266 None, | |
| 267 ImplicitResolve, | |
| 268 ExplicitResolve, | |
| 269 }; | |
| 270 | |
| 271 MultisampleMode m_multisampleMode; | |
| 272 | |
| 273 WebGraphicsContext3D::Attributes m_actualAttributes; | |
| 274 unsigned m_internalColorFormat; | |
| 275 unsigned m_colorFormat; | |
| 276 unsigned m_internalRenderbufferFormat; | |
| 277 int m_maxTextureSize; | |
| 278 int m_sampleCount; | |
| 279 int m_packAlignment; | |
| 280 bool m_destructionInProgress; | |
| 281 bool m_isHidden; | |
| 282 | |
| 283 OwnPtr<WebExternalTextureLayer> m_layer; | |
| 284 | |
| 285 // All of the mailboxes that this DrawingBuffer has ever created. | |
| 286 Vector<RefPtr<MailboxInfo> > m_textureMailboxes; | |
| 287 // Mailboxes that were released by the compositor can be used again by this
DrawingBuffer. | |
| 288 Deque<WebExternalTextureMailbox> m_recycledMailboxQueue; | |
| 289 | |
| 290 RefPtr<ContextEvictionManager> m_contextEvictionManager; | |
| 291 | |
| 292 // If the width and height of the Canvas's backing store don't | |
| 293 // match those that we were given in the most recent call to | |
| 294 // reshape(), then we need an intermediate bitmap to read back the | |
| 295 // frame buffer into. This seems to happen when CSS styles are | |
| 296 // used to resize the Canvas. | |
| 297 SkBitmap m_resizingBitmap; | |
| 298 | |
| 299 // Used to flip a bitmap vertically. | |
| 300 Vector<uint8_t> m_scanline; | |
| 301 }; | |
| 302 | |
| 303 } // namespace blink | |
| 304 | |
| 305 #endif // SKY_ENGINE_PLATFORM_GRAPHICS_GPU_DRAWINGBUFFER_H_ | |
| OLD | NEW |