// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the mock GLES2Decoder class.

#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_MOCK_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_MOCK_H_

#include <stdint.h>

#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/shader_translator.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/gfx/geometry/size.h"

namespace gl {
class GLContext;
class GLSurface;
}

namespace gpu {

namespace gles2 {

class ContextGroup;
class ErrorState;
class GpuFenceManager;
class QueryManager;
struct ContextState;

class MockGLES2Decoder : public GLES2Decoder {
 public:
  MockGLES2Decoder(CommandBufferServiceBase* command_buffer_service,
                   Outputter* outputter);
  virtual ~MockGLES2Decoder();

  base::WeakPtr<GLES2Decoder> AsWeakPtr() override;

  MOCK_METHOD5(Initialize,
               gpu::ContextResult(const scoped_refptr<gl::GLSurface>& surface,
                                  const scoped_refptr<gl::GLContext>& context,
                                  bool offscreen,
                                  const DisallowedFeatures& disallowed_features,
                                  const ContextCreationAttribs& attrib_helper));
  MOCK_METHOD1(Destroy, void(bool have_context));
  MOCK_METHOD1(SetSurface, void(const scoped_refptr<gl::GLSurface>& surface));
  MOCK_METHOD0(ReleaseSurface, void());
  MOCK_METHOD1(TakeFrontBuffer, void(const Mailbox& mailbox));
  MOCK_METHOD2(ReturnFrontBuffer, void(const Mailbox& mailbox, bool is_lost));
  MOCK_METHOD0(GetSavedBackTextureCountForTest, size_t());
  MOCK_METHOD0(GetCreatedBackTextureCountForTest, size_t());
  MOCK_METHOD1(ResizeOffscreenFramebuffer, bool(const gfx::Size& size));
  MOCK_METHOD0(MakeCurrent, bool());
  MOCK_METHOD1(GetServiceIdForTesting, uint32_t(uint32_t client_id));
  MOCK_METHOD0(GetGLES2Util, GLES2Util*());
  MOCK_METHOD0(GetGLSurface, gl::GLSurface*());
  MOCK_METHOD0(GetGLContext, gl::GLContext*());
  MOCK_METHOD0(GetContextGroup, ContextGroup*());
  MOCK_CONST_METHOD0(GetFeatureInfo, const FeatureInfo*());
  MOCK_METHOD0(GetContextState, const ContextState*());
  MOCK_METHOD1(GetTranslator,
               scoped_refptr<ShaderTranslatorInterface>(unsigned int type));
  MOCK_METHOD0(GetCapabilities, Capabilities());
  MOCK_CONST_METHOD0(HasPendingQueries, bool());
  MOCK_METHOD1(ProcessPendingQueries, void(bool));
  MOCK_CONST_METHOD0(HasMoreIdleWork, bool());
  MOCK_METHOD0(PerformIdleWork, void());
  MOCK_CONST_METHOD0(HasPollingWork, bool());
  MOCK_METHOD0(PerformPollingWork, void());
  MOCK_METHOD1(RestoreState, void(const ContextState* prev_state));
  MOCK_CONST_METHOD0(RestoreActiveTexture, void());
  MOCK_CONST_METHOD1(RestoreAllTextureUnitAndSamplerBindings,
                     void(const ContextState* state));
  MOCK_CONST_METHOD1(
      RestoreActiveTextureUnitBinding, void(unsigned int target));
  MOCK_METHOD0(RestoreAllExternalTextureBindingsIfNeeded, void());
  MOCK_METHOD1(RestoreBufferBinding, void(unsigned int target));
  MOCK_CONST_METHOD0(RestoreBufferBindings, void());
  MOCK_CONST_METHOD0(RestoreFramebufferBindings, void());
  MOCK_CONST_METHOD0(RestoreGlobalState, void());
  MOCK_CONST_METHOD0(RestoreProgramBindings, void());
  MOCK_METHOD0(RestoreRenderbufferBindings, void());
  MOCK_CONST_METHOD1(RestoreTextureState, void(unsigned service_id));
  MOCK_CONST_METHOD1(RestoreTextureUnitBindings, void(unsigned unit));
  MOCK_METHOD1(RestoreVertexAttribArray, void(unsigned index));
  MOCK_CONST_METHOD0(RestoreDeviceWindowRectangles, void());
  MOCK_CONST_METHOD0(ClearAllAttributes, void());
  MOCK_CONST_METHOD0(RestoreAllAttributes, void());
  MOCK_METHOD0(GetQueryManager, gpu::gles2::QueryManager*());
  MOCK_METHOD0(GetGpuFenceManager, gpu::gles2::GpuFenceManager*());
  MOCK_METHOD0(GetFramebufferManager, gpu::gles2::FramebufferManager*());
  MOCK_METHOD0(
      GetTransformFeedbackManager, gpu::gles2::TransformFeedbackManager*());
  MOCK_METHOD0(GetVertexArrayManager, gpu::gles2::VertexArrayManager*());
  MOCK_METHOD0(GetImageManagerForTest, gpu::gles2::ImageManager*());
  MOCK_METHOD1(
      SetResizeCallback, void(const base::Callback<void(gfx::Size, float)>&));
  MOCK_METHOD1(SetIgnoreCachedStateForTest, void(bool ignore));
  MOCK_METHOD1(SetForceShaderNameHashingForTest, void(bool force));
  MOCK_METHOD1(SetAllowExit, void(bool allow));
  MOCK_METHOD4(DoCommands,
               error::Error(unsigned int num_commands,
                            const volatile void* buffer,
                            int num_entries,
                            int* entries_processed));
  MOCK_METHOD2(GetServiceTextureId,
               bool(uint32_t client_texture_id, uint32_t* service_texture_id));
  MOCK_METHOD9(ClearLevel,
               bool(Texture* texture,
                    unsigned target,
                    int level,
                    unsigned format,
                    unsigned type,
                    int x_offset,
                    int y_offset,
                    int width,
                    int height));
  MOCK_METHOD6(ClearCompressedTextureLevel,
               bool(Texture* texture,
                    unsigned target,
                    int level,
                    unsigned format,
                    int width,
                    int height));
  MOCK_METHOD1(IsCompressedTextureFormat,
               bool(unsigned format));
  MOCK_METHOD8(ClearLevel3D,
               bool(Texture* texture,
                    unsigned target,
                    int level,
                    unsigned format,
                    unsigned type,
                    int width,
                    int height,
                    int depth));
  MOCK_METHOD0(GetErrorState, ErrorState *());

  MOCK_METHOD0(GetLogger, Logger*());
  MOCK_METHOD1(WaitForReadPixels,
               void(base::Closure callback));
  MOCK_CONST_METHOD0(WasContextLost, bool());
  MOCK_CONST_METHOD0(WasContextLostByRobustnessExtension, bool());
  MOCK_METHOD1(MarkContextLost, void(gpu::error::ContextLostReason reason));
  MOCK_METHOD0(CheckResetStatus, bool());
  MOCK_METHOD4(BindImage,
               void(uint32_t client_texture_id,
                    uint32_t texture_target,
                    gl::GLImage* image,
                    bool can_bind_to_sampler));

 private:
  base::WeakPtrFactory<MockGLES2Decoder> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(MockGLES2Decoder);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_MOCK_H_
