/*
 * Copyright (c) 2010, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef DrawingBuffer_h
#define DrawingBuffer_h

#include "platform/PlatformExport.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/GraphicsTypes3D.h"
#include "platform/graphics/gpu/WebGLImageConversion.h"
#include "public/platform/WebExternalTextureLayerClient.h"
#include "public/platform/WebExternalTextureMailbox.h"
#include "public/platform/WebGraphicsContext3D.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "wtf/Deque.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"

namespace blink {

class Extensions3DUtil;
class ImageBuffer;
class WebExternalBitmap;
class WebExternalTextureLayer;
class WebGraphicsContext3D;
class WebLayer;

// Abstract interface to allow basic context eviction management
class PLATFORM_EXPORT ContextEvictionManager : public RefCounted<ContextEvictionManager> {
public:
    virtual ~ContextEvictionManager() {};

    virtual void forciblyLoseOldestContext(const String& reason) = 0;
    virtual IntSize oldestContextSize() = 0;
};

// Manages a rendering target (framebuffer + attachment) for a canvas.  Can publish its rendering
// results to a WebLayer for compositing.
class PLATFORM_EXPORT DrawingBuffer : public RefCounted<DrawingBuffer>, public WebExternalTextureLayerClient  {
    // If we used CHROMIUM_image as the backing storage for our buffers,
    // we need to know the mapping from texture id to image.
    struct TextureInfo {
        Platform3DObject textureId;
        WGC3Duint imageId;

        TextureInfo()
            : textureId(0)
            , imageId(0)
        {
        }
    };

    struct MailboxInfo : public RefCounted<MailboxInfo> {
        WebExternalTextureMailbox mailbox;
        TextureInfo textureInfo;
        IntSize size;
        // This keeps the parent drawing buffer alive as long as the compositor is
        // referring to one of the mailboxes DrawingBuffer produced. The parent drawing buffer is
        // cleared when the compositor returns the mailbox. See mailboxReleased().
        RefPtr<DrawingBuffer> m_parentDrawingBuffer;
    };
public:
    enum PreserveDrawingBuffer {
        Preserve,
        Discard
    };

    static PassRefPtr<DrawingBuffer> create(PassOwnPtr<WebGraphicsContext3D>, const IntSize&, PreserveDrawingBuffer, WebGraphicsContext3D::Attributes requestedAttributes, PassRefPtr<ContextEvictionManager>);

    virtual ~DrawingBuffer();

    // Destruction will be completed after all mailboxes are released.
    void beginDestruction();

    // Issues a glClear() on all framebuffers associated with this DrawingBuffer. The caller is responsible for
    // making the context current and setting the clear values and masks. Modifies the framebuffer binding.
    void clearFramebuffers(GLbitfield clearMask);

    // Given the desired buffer size, provides the largest dimensions that will fit in the pixel budget.
    static IntSize adjustSize(const IntSize& desiredSize, const IntSize& curSize, int maxTextureSize);
    bool reset(const IntSize&);
    void bind();
    IntSize size() const { return m_size; }

    // Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound.
    void commit(long x = 0, long y = 0, long width = -1, long height = -1);

    // commit should copy the full multisample buffer, and not respect the
    // current scissor bounds. Track the state of the scissor test so that it
    // can be disabled during calls to commit.
    void setScissorEnabled(bool scissorEnabled) { m_scissorEnabled = scissorEnabled; }

    // The DrawingBuffer needs to track the texture bound to texture unit 0.
    // The bound texture is tracked to avoid costly queries during rendering.
    void setTexture2DBinding(Platform3DObject texture) { m_texture2DBinding = texture; }

    // The DrawingBuffer needs to track the currently bound framebuffer so it
    // restore the binding when needed.
    void setFramebufferBinding(Platform3DObject fbo) { m_framebufferBinding = fbo; }

    // Track the currently active texture unit. Texture unit 0 is used as host for a scratch
    // texture.
    void setActiveTextureUnit(GLint textureUnit) { m_activeTextureUnit = textureUnit; }

    bool multisample() const;

    Platform3DObject framebuffer() const;

    bool discardFramebufferSupported() const { return m_discardFramebufferSupported; }

    void markContentsChanged();
    void markLayerComposited();
    bool layerComposited() const;
    void setIsHidden(bool);

    WebLayer* platformLayer();

    WebGraphicsContext3D* context();

    // Returns the actual context attributes for this drawing buffer which may differ from the
    // requested context attributes due to implementation limits.
    WebGraphicsContext3D::Attributes getActualAttributes() const { return m_actualAttributes; }

    // WebExternalTextureLayerClient implementation.
    virtual bool prepareMailbox(WebExternalTextureMailbox*, WebExternalBitmap*) override;
    virtual void mailboxReleased(const WebExternalTextureMailbox&, bool lostResource = false) override;

    enum SourceBuffer { Front, Back };
    // Destroys the TEXTURE_2D binding for the owned context
    bool copyToPlatformTexture(WebGraphicsContext3D*, Platform3DObject texture, GLenum internalFormat,
        GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, SourceBuffer);

    void setPackAlignment(GLint param);

    void paintRenderingResultsToCanvas(ImageBuffer*);
    PassRefPtr<Uint8ClampedArray> paintRenderingResultsToImageData(int&, int&);

protected: // For unittests
    DrawingBuffer(
        PassOwnPtr<WebGraphicsContext3D>,
        PassOwnPtr<Extensions3DUtil>,
        bool multisampleExtensionSupported,
        bool packedDepthStencilExtensionSupported,
        bool discardFramebufferSupported,
        PreserveDrawingBuffer,
        WebGraphicsContext3D::Attributes requestedAttributes,
        PassRefPtr<ContextEvictionManager>);

    bool initialize(const IntSize&);

private:
    void mailboxReleasedWithoutRecycling(const WebExternalTextureMailbox&);

    unsigned createColorTexture();
    // Create the depth/stencil and multisample buffers, if needed.
    void createSecondaryBuffers();
    bool resizeFramebuffer(const IntSize&);
    bool resizeMultisampleFramebuffer(const IntSize&);
    void resizeDepthStencil(const IntSize&);

    // Bind to the m_framebufferBinding if it's not 0.
    void restoreFramebufferBinding();

    void clearPlatformLayer();

    PassRefPtr<MailboxInfo> recycledMailbox();
    PassRefPtr<MailboxInfo> createNewMailbox(const TextureInfo&);
    void deleteMailbox(const WebExternalTextureMailbox&);
    void freeRecycledMailboxes();

    // Updates the current size of the buffer, ensuring that s_currentResourceUsePixels is updated.
    void setSize(const IntSize& size);

    // Calculates the difference in pixels between the current buffer size and the proposed size.
    static int pixelDelta(const IntSize& newSize, const IntSize& curSize);

    // Given the desired buffer size, provides the largest dimensions that will fit in the pixel budget
    // Returns true if the buffer will only fit if the oldest WebGL context is forcibly lost
    IntSize adjustSizeWithContextEviction(const IntSize&, bool& evictContext);

    void paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer*);

    // This is the order of bytes to use when doing a readback.
    enum ReadbackOrder {
        ReadbackRGBA,
        ReadbackSkia
    };

    // Helper function which does a readback from the currently-bound
    // framebuffer into a buffer of a certain size with 4-byte pixels.
    void readBackFramebuffer(unsigned char* pixels, int width, int height, ReadbackOrder, WebGLImageConversion::AlphaOp);

    // Helper function to flip a bitmap vertically.
    void flipVertically(uint8_t* data, int width, int height);

    // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
    // By default, alignment is 4, the OpenGL default setting.
    void texImage2DResourceSafe(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint alignment = 4);
    // Allocate buffer storage to be sent to compositor using either texImage2D or CHROMIUM_image based on available support.
    void allocateTextureMemory(TextureInfo*, const IntSize&);
    void deleteChromiumImageForTexture(TextureInfo*);

    PreserveDrawingBuffer m_preserveDrawingBuffer;
    bool m_scissorEnabled;
    Platform3DObject m_texture2DBinding;
    Platform3DObject m_framebufferBinding;
    GLenum m_activeTextureUnit;

    OwnPtr<WebGraphicsContext3D> m_context;
    OwnPtr<Extensions3DUtil> m_extensionsUtil;
    IntSize m_size;
    WebGraphicsContext3D::Attributes m_requestedAttributes;
    bool m_multisampleExtensionSupported;
    bool m_packedDepthStencilExtensionSupported;
    bool m_discardFramebufferSupported;
    Platform3DObject m_fbo;
    // DrawingBuffer's output is double-buffered. m_colorBuffer is the back buffer.
    TextureInfo m_colorBuffer;
    struct FrontBufferInfo {
        TextureInfo texInfo;
        WebExternalTextureMailbox mailbox;
    };
    FrontBufferInfo m_frontColorBuffer;

    // This is used when we have OES_packed_depth_stencil.
    Platform3DObject m_depthStencilBuffer;

    // These are used when we don't.
    Platform3DObject m_depthBuffer;
    Platform3DObject m_stencilBuffer;

    // For multisampling.
    Platform3DObject m_multisampleFBO;
    Platform3DObject m_multisampleColorBuffer;

    // True if our contents have been modified since the last presentation of this buffer.
    bool m_contentsChanged;

    // True if commit() has been called since the last time markContentsChanged() had been called.
    bool m_contentsChangeCommitted;
    bool m_layerComposited;

    enum MultisampleMode {
        None,
        ImplicitResolve,
        ExplicitResolve,
    };

    MultisampleMode m_multisampleMode;

    WebGraphicsContext3D::Attributes m_actualAttributes;
    unsigned m_internalColorFormat;
    unsigned m_colorFormat;
    unsigned m_internalRenderbufferFormat;
    int m_maxTextureSize;
    int m_sampleCount;
    int m_packAlignment;
    bool m_destructionInProgress;
    bool m_isHidden;

    OwnPtr<WebExternalTextureLayer> m_layer;

    // All of the mailboxes that this DrawingBuffer has ever created.
    Vector<RefPtr<MailboxInfo> > m_textureMailboxes;
    // Mailboxes that were released by the compositor can be used again by this DrawingBuffer.
    Deque<WebExternalTextureMailbox> m_recycledMailboxQueue;

    RefPtr<ContextEvictionManager> m_contextEvictionManager;

    // If the width and height of the Canvas's backing store don't
    // match those that we were given in the most recent call to
    // reshape(), then we need an intermediate bitmap to read back the
    // frame buffer into. This seems to happen when CSS styles are
    // used to resize the Canvas.
    SkBitmap m_resizingBitmap;

    // Used to flip a bitmap vertically.
    Vector<uint8_t> m_scanline;
};

} // namespace blink

#endif // DrawingBuffer_h
