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