Home | History | Annotate | Download | only in gpu
      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 DrawingBuffer_h
     32 #define DrawingBuffer_h
     33 
     34 #include "platform/PlatformExport.h"
     35 #include "platform/geometry/IntSize.h"
     36 #include "platform/graphics/GraphicsContext3D.h"
     37 #include "platform/graphics/GraphicsTypes3D.h"
     38 
     39 #include "public/platform/WebExternalTextureLayerClient.h"
     40 #include "public/platform/WebExternalTextureMailbox.h"
     41 #include "wtf/Noncopyable.h"
     42 #include "wtf/OwnPtr.h"
     43 #include "wtf/PassOwnPtr.h"
     44 
     45 namespace blink {
     46 class WebExternalBitmap;
     47 class WebExternalTextureLayer;
     48 class WebGraphicsContext3D;
     49 class WebLayer;
     50 }
     51 
     52 namespace WebCore {
     53 class GraphicsContext3D;
     54 class ImageData;
     55 
     56 // Abstract interface to allow basic context eviction management
     57 class PLATFORM_EXPORT ContextEvictionManager : public RefCounted<ContextEvictionManager> {
     58 public:
     59     virtual ~ContextEvictionManager() {};
     60 
     61     virtual void forciblyLoseOldestContext(const String& reason) = 0;
     62     virtual IntSize oldestContextSize() = 0;
     63 };
     64 
     65 // Manages a rendering target (framebuffer + attachment) for a canvas.  Can publish its rendering
     66 // results to a blink::WebLayer for compositing.
     67 class PLATFORM_EXPORT DrawingBuffer : public RefCounted<DrawingBuffer>, public blink::WebExternalTextureLayerClient  {
     68     struct MailboxInfo : public RefCounted<MailboxInfo> {
     69         blink::WebExternalTextureMailbox mailbox;
     70         unsigned textureId;
     71         IntSize size;
     72     };
     73 public:
     74     enum PreserveDrawingBuffer {
     75         Preserve,
     76         Discard
     77     };
     78 
     79     static PassRefPtr<DrawingBuffer> create(GraphicsContext3D*, const IntSize&, PreserveDrawingBuffer, PassRefPtr<ContextEvictionManager>);
     80 
     81     ~DrawingBuffer();
     82 
     83     // Clear all resources from this object, as well as context. Called when context is destroyed
     84     // to prevent invalid accesses to the resources.
     85     void releaseResources();
     86 
     87     // Issues a glClear() on all framebuffers associated with this DrawingBuffer. The caller is responsible for
     88     // making the context current and setting the clear values and masks. Modifies the framebuffer binding.
     89     void clearFramebuffers(GC3Dbitfield clearMask);
     90 
     91     // Given the desired buffer size, provides the largest dimensions that will fit in the pixel budget.
     92     IntSize adjustSize(const IntSize&);
     93     void reset(const IntSize&);
     94     void bind();
     95     IntSize size() const { return m_size; }
     96     bool isZeroSized() const { return m_size.isEmpty(); }
     97 
     98     // Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound.
     99     void commit(long x = 0, long y = 0, long width = -1, long height = -1);
    100 
    101     // commit should copy the full multisample buffer, and not respect the
    102     // current scissor bounds. Track the state of the scissor test so that it
    103     // can be disabled during calls to commit.
    104     void setScissorEnabled(bool scissorEnabled) { m_scissorEnabled = scissorEnabled; }
    105 
    106     // The DrawingBuffer needs to track the texture bound to texture unit 0.
    107     // The bound texture is tracked to avoid costly queries during rendering.
    108     void setTexture2DBinding(Platform3DObject texture) { m_texture2DBinding = texture; }
    109 
    110     // The DrawingBuffer needs to track the currently bound framebuffer so it
    111     // restore the binding when needed.
    112     void setFramebufferBinding(Platform3DObject fbo) { m_framebufferBinding = fbo; }
    113 
    114     // Track the currently active texture unit. Texture unit 0 is used as host for a scratch
    115     // texture.
    116     void setActiveTextureUnit(GC3Dint textureUnit) { m_activeTextureUnit = textureUnit; }
    117 
    118     bool multisample() const;
    119 
    120     Platform3DObject framebuffer() const;
    121 
    122     void markContentsChanged();
    123 
    124     blink::WebLayer* platformLayer();
    125     void paintCompositedResultsToCanvas(ImageBuffer*);
    126 
    127     // WebExternalTextureLayerClient implementation.
    128     virtual blink::WebGraphicsContext3D* context() OVERRIDE;
    129     virtual bool prepareMailbox(blink::WebExternalTextureMailbox*, blink::WebExternalBitmap*) OVERRIDE;
    130     virtual void mailboxReleased(const blink::WebExternalTextureMailbox&) OVERRIDE;
    131 
    132     bool copyToPlatformTexture(GraphicsContext3D&, Platform3DObject texture, GC3Denum internalFormat,
    133         GC3Denum destType, GC3Dint level, bool premultiplyAlpha, bool flipY);
    134 
    135 private:
    136     DrawingBuffer(GraphicsContext3D*, const IntSize&, bool multisampleExtensionSupported,
    137                   bool packedDepthStencilExtensionSupported, PreserveDrawingBuffer, PassRefPtr<ContextEvictionManager>);
    138 
    139     void initialize(const IntSize&);
    140 
    141     Platform3DObject frontColorBuffer() const;
    142     Platform3DObject colorBuffer() const { return m_colorBuffer; }
    143 
    144     unsigned createColorTexture(const IntSize& size = IntSize());
    145     // Create the depth/stencil and multisample buffers, if needed.
    146     void createSecondaryBuffers();
    147     bool resizeFramebuffer(const IntSize&);
    148     bool resizeMultisampleFramebuffer(const IntSize&);
    149     void resizeDepthStencil(const IntSize&, int sampleCount);
    150 
    151     // Bind to the m_framebufferBinding if it's not 0.
    152     void restoreFramebufferBinding();
    153 
    154     void clearPlatformLayer();
    155 
    156     PassRefPtr<MailboxInfo> recycledMailbox();
    157     PassRefPtr<MailboxInfo> createNewMailbox(unsigned);
    158 
    159     // Updates the current size of the buffer, ensuring that s_currentResourceUsePixels is updated.
    160     void setSize(const IntSize& size);
    161 
    162     // Calculates the difference in pixels between the current buffer size and the proposed size.
    163     int pixelDelta(const IntSize& size);
    164 
    165     // Given the desired buffer size, provides the largest dimensions that will fit in the pixel budget
    166     // Returns true if the buffer will only fit if the oldest WebGL context is forcibly lost
    167     IntSize adjustSizeWithContextEviction(const IntSize&, bool& evictContext);
    168 
    169     PreserveDrawingBuffer m_preserveDrawingBuffer;
    170     bool m_scissorEnabled;
    171     Platform3DObject m_texture2DBinding;
    172     Platform3DObject m_framebufferBinding;
    173     GC3Denum m_activeTextureUnit;
    174 
    175     RefPtr<GraphicsContext3D> m_context;
    176     IntSize m_size;
    177     bool m_multisampleExtensionSupported;
    178     bool m_packedDepthStencilExtensionSupported;
    179     Platform3DObject m_fbo;
    180     Platform3DObject m_colorBuffer;
    181     Platform3DObject m_frontColorBuffer;
    182 
    183     // This is used when we have OES_packed_depth_stencil.
    184     Platform3DObject m_depthStencilBuffer;
    185 
    186     // These are used when we don't.
    187     Platform3DObject m_depthBuffer;
    188     Platform3DObject m_stencilBuffer;
    189 
    190     // For multisampling.
    191     Platform3DObject m_multisampleFBO;
    192     Platform3DObject m_multisampleColorBuffer;
    193 
    194     // True if our contents have been modified since the last presentation of this buffer.
    195     bool m_contentsChanged;
    196 
    197     // True if commit() has been called since the last time markContentsChanged() had been called.
    198     bool m_contentsChangeCommitted;
    199 
    200     GraphicsContext3D::Attributes m_attributes;
    201     unsigned m_internalColorFormat;
    202     unsigned m_colorFormat;
    203     unsigned m_internalRenderbufferFormat;
    204     int m_maxTextureSize;
    205 
    206     OwnPtr<blink::WebExternalTextureLayer> m_layer;
    207 
    208     // All of the mailboxes that this DrawingBuffer has ever created.
    209     Vector<RefPtr<MailboxInfo> > m_textureMailboxes;
    210     // Mailboxes that were released by the compositor and can be used again by this DrawingBuffer.
    211     Vector<RefPtr<MailboxInfo> > m_recycledMailboxes;
    212     RefPtr<MailboxInfo> m_lastColorBuffer;
    213 
    214     RefPtr<ContextEvictionManager> m_contextEvictionManager;
    215 };
    216 
    217 } // namespace WebCore
    218 
    219 #endif // DrawingBuffer_h
    220