15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests for GLES2Implementation.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <limits>
10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2ext.h>
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <GLES2/gl2extchromium.h>
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/compiler_specific.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/client_test_helper.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/program_info_manager.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/client/transfer_buffer.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/command_buffer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::AtLeast;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AnyNumber;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InSequence;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Invoke;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Sequence;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::StrictMock;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Truly;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P2(SetMemory, dst, obj) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, &obj, sizeof(obj));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P3(SetMemoryFromArray, dst, array, size) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst, array, size);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to help set the transfer buffer result to SizedResult of a single value.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T>
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SizedResultHelper {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SizedResultHelper(T result)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : size_(sizeof(result)),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result_(result) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 size_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T result_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Struct to make it easy to pass a vec4 worth of floats.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct FourFloats {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FourFloats(float _x, float _y, float _z, float _w)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : x(_x),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        y(_y),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        z(_z),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        w(_w) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float x;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float y;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float z;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float w;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma pack(push, 1)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Struct that holds 7 characters.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Str7 {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char str[7];
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma pack(pop)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockTransferBuffer : public TransferBufferInterface {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ExpectedMemoryInfo {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 offset;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 id;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* ptr;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTransferBuffer(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommandBuffer* command_buffer,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int result_size,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int alignment)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : command_buffer_(command_buffer),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size_(size),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result_size_(result_size),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alignment_(alignment),
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        actual_buffer_index_(0),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        expected_buffer_index_(0),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_alloc_(NULL),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        expected_offset_(result_size),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        actual_offset_(result_size) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to allocate the buffers here because
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we need to know their address before GLES2Implementation::Initialize
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is called.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int ii = 0; ii < kNumBuffers; ++ii) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      buffers_[ii] = command_buffer_->CreateTransferBuffer(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          size_ + ii * alignment_,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &buffer_ids_[ii]);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_NE(-1, buffer_ids_[ii]);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MockTransferBuffer() { }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool Initialize(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int starting_buffer_size,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int result_size,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int /* min_buffer_size */,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int /* max_buffer_size */,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int alignment,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size_to_flush) OVERRIDE;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetShmId() OVERRIDE;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* GetResultBuffer() OVERRIDE;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetResultOffset() OVERRIDE;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Free() OVERRIDE;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HaveBuffer() const OVERRIDE;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* AllocUpTo(
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size, unsigned int* size_allocated) OVERRIDE;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* Alloc(unsigned int size) OVERRIDE;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FreePendingToken(void* p, unsigned int /* token */) OVERRIDE;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t MaxTransferBufferSize() {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size_ - result_size_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int RoundToAlignment(unsigned int size) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (size + alignment_ - 1) & ~(alignment_ - 1);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InSync() {
146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return expected_buffer_index_ == actual_buffer_index_ &&
147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)           expected_offset_ == actual_offset_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo GetExpectedMemory(size_t size) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedMemoryInfo mem;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem.offset = AllocateExpectedTransferBuffer(size);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem.id = GetExpectedTransferBufferId();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem.ptr = static_cast<uint8*>(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       GetExpectedTransferAddressFromOffset(mem.offset, size));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return mem;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedMemoryInfo mem;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem.offset = GetExpectedResultBufferOffset();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem.id = GetExpectedResultBufferId();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem.ptr = static_cast<uint8*>(
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetExpectedTransferAddressFromOffset(mem.offset, size));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return mem;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNumBuffers = 2;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* actual_buffer() const {
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* expected_buffer() const {
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 AllocateExpectedTransferBuffer(size_t size) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LE(size, MaxTransferBufferSize());
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Toggle which buffer we get each time to simulate the buffer being
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reallocated.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_offset_ + size > size_) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_offset_ = result_size_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 offset = expected_offset_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_offset_ += RoundToAlignment(size);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure each buffer has a different offset.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return offset + expected_buffer_index_ * alignment_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GE(offset, expected_buffer_index_ * alignment_);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return expected_buffer() + offset;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetExpectedResultBufferId() {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buffer_ids_[expected_buffer_index_];
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetExpectedResultBufferOffset() {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return expected_buffer_index_ * alignment_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetExpectedTransferBufferId() {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buffer_ids_[expected_buffer_index_];
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBuffer* command_buffer_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t size_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t result_size_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 alignment_;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int buffer_ids_[kNumBuffers];
219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_refptr<Buffer> buffers_[kNumBuffers];
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int actual_buffer_index_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_buffer_index_;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* last_alloc_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 expected_offset_;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 actual_offset_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockTransferBuffer::Initialize(
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int starting_buffer_size,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int result_size,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int /* min_buffer_size */,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int /* max_buffer_size */,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int alignment,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int /* size_to_flush */) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just check they match.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return size_ == starting_buffer_size &&
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         result_size_ == result_size &&
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         alignment_ == alignment;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MockTransferBuffer::GetShmId() {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return buffer_ids_[actual_buffer_index_];
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* MockTransferBuffer::GetResultBuffer() {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return actual_buffer() + actual_buffer_index_ * alignment_;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MockTransferBuffer::GetResultOffset() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return actual_buffer_index_ * alignment_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockTransferBuffer::Free() {
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTREACHED();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockTransferBuffer::HaveBuffer() const {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* MockTransferBuffer::AllocUpTo(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int size, unsigned int* size_allocated) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(size_allocated != NULL);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(last_alloc_ == NULL);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Toggle which buffer we get each time to simulate the buffer being
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reallocated.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (actual_offset_ + size > size_) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    actual_offset_ = result_size_;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 offset = actual_offset_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  actual_offset_ += RoundToAlignment(size);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *size_allocated = size;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure each buffer has a different offset.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return last_alloc_;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* MockTransferBuffer::Alloc(unsigned int size) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(size, MaxTransferBufferSize());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int temp = 0;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* p = AllocUpTo(size, &temp);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(temp, size);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return p;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure each buffer has a different offset.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<uint8*>(pointer) - actual_buffer();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_alloc_, p);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_alloc_ = NULL;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// API wrapper for Buffers.
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GenBuffersAPI {
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->GenBuffers(n, ids);
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Delete(GLES2Implementation* gl_impl,
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     GLsizei n,
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const GLuint* ids) {
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->DeleteBuffers(n, ids);
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// API wrapper for Framebuffers.
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GenFramebuffersAPI {
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->GenFramebuffers(n, ids);
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Delete(GLES2Implementation* gl_impl,
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     GLsizei n,
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const GLuint* ids) {
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->DeleteFramebuffers(n, ids);
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// API wrapper for Renderbuffers.
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GenRenderbuffersAPI {
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->GenRenderbuffers(n, ids);
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Delete(GLES2Implementation* gl_impl,
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     GLsizei n,
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const GLuint* ids) {
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->DeleteRenderbuffers(n, ids);
341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// API wrapper for Textures.
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GenTexturesAPI {
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->GenTextures(n, ids);
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static void Delete(GLES2Implementation* gl_impl,
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     GLsizei n,
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const GLuint* ids) {
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_impl->DeleteTextures(n, ids);
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2ImplementationTest : public testing::Test {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static const int kNumTestContexts = 2;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 kInitialValue = 0xBD;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int32 kNumCommandEntries = 500;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int32 kCommandBufferSizeBytes =
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kNumCommandEntries * sizeof(CommandBufferEntry);
365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  static const size_t kTransferBufferSize = 512;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxCombinedTextureImageUnits = 8;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxCubeMapTextureSize = 64;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxFragmentUniformVectors = 16;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxRenderbufferSize = 64;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxTextureImageUnits = 8;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxTextureSize = 128;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxVaryingVectors = 8;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxVertexAttribs = 8;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxVertexTextureImageUnits = 0;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kMaxVertexUniformVectors = 128;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kNumCompressedTextureFormats = 0;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kNumShaderBinaryFormats = 0;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kStartId = 1024;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kBuffersStartId =
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kFramebuffersStartId = 1;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kProgramsAndShadersStartId = 1;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kRenderbuffersStartId = 1;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kTexturesStartId = 1;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kQueriesStartId = 1;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kVertexArraysStartId = 1;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  class TestContext {
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)   public:
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TestContext() : commands_(NULL), token_(0) {}
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool Initialize(ShareGroup* share_group,
3966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                    bool bind_generates_resource_client,
3976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                    bool bind_generates_resource_service,
398e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                    bool lose_context_when_out_of_memory) {
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      if (!command_buffer_->Initialize())
401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return false;
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      transfer_buffer_.reset(
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          new MockTransferBuffer(command_buffer_.get(),
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 kTransferBufferSize,
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 GLES2Implementation::kStartingOffset,
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 GLES2Implementation::kAlignment));
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      helper_.reset(new GLES2CmdHelper(command_buffer()));
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      helper_->Initialize(kCommandBufferSizeBytes);
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      gpu_control_.reset(new StrictMock<MockClientGpuControl>());
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      EXPECT_CALL(*gpu_control_, GetCapabilities())
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .WillOnce(testing::Return(Capabilities()));
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GLES2Implementation::GLStaticState state;
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GLES2Implementation::GLStaticState::IntState& int_state = state.int_state;
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_combined_texture_image_units =
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          kMaxCombinedTextureImageUnits;
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize;
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_renderbuffer_size = kMaxRenderbufferSize;
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_texture_image_units = kMaxTextureImageUnits;
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_texture_size = kMaxTextureSize;
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_varying_vectors = kMaxVaryingVectors;
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_vertex_attribs = kMaxVertexAttribs;
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.num_compressed_texture_formats = kNumCompressedTextureFormats;
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int_state.num_shader_binary_formats = kNumShaderBinaryFormats;
431c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      int_state.bind_generates_resource_chromium =
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          bind_generates_resource_service ? 1 : 0;
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // This just happens to work for now because IntState has 1 GLint per
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // state.
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // If IntState gets more complicated this code will need to get more
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // complicated.
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory(
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          sizeof(GLES2Implementation::GLStaticState::IntState) * 2 +
440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          sizeof(cmds::GetShaderPrecisionFormat::Result) * 12);
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      {
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        InSequence sequence;
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        EXPECT_CALL(*command_buffer_, OnFlush())
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state))
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            .RetiresOnSaturation();
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        GetNextToken();  // eat the token that starting up will use.
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
450e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        gl_.reset(new GLES2Implementation(helper_.get(),
451e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                          share_group,
452e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                          transfer_buffer_.get(),
4536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                          bind_generates_resource_client,
454e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                          lose_context_when_out_of_memory,
455e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                          gpu_control_.get()));
456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        if (!gl_->Initialize(kTransferBufferSize,
458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                             kTransferBufferSize,
459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                             kTransferBufferSize,
460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                             GLES2Implementation::kNoLimit))
461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          return false;
462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation();
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      helper_->CommandBufferHelper::Finish();
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ::testing::Mock::VerifyAndClearExpectations(gl_.get());
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
4705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  command_buffer()->GetLastState().put_offset;
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ClearCommands();
472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      EXPECT_TRUE(transfer_buffer_->InSync());
473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ::testing::Mock::VerifyAndClearExpectations(command_buffer());
475c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return true;
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    void TearDown() {
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Mock::VerifyAndClear(gl_.get());
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // For command buffer.
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          .Times(AtLeast(1));
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      gl_.reset();
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MockClientCommandBuffer* command_buffer() const {
488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return command_buffer_.get();
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int GetNextToken() { return ++token_; }
492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    void ClearCommands() {
494effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
495effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<MockClientCommandBuffer> command_buffer_;
499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<MockClientGpuControl> gpu_control_;
500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<GLES2CmdHelper> helper_;
501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<MockTransferBuffer> transfer_buffer_;
502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_ptr<GLES2Implementation> gl_;
503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CommandBufferEntry* commands_;
504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int token_;
505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GLES2ImplementationTest() : commands_(NULL) {}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool NoCommandsWritten() {
513effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
514effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
515effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const uint8* end = cmds + ring_buffer->size();
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (; cmds < end; ++cmds) {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*cmds != kInitialValue) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryTracker::Query* GetQuery(GLuint id) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gl_->query_tracker_->GetQuery(id);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  struct ContextInitOptions {
529c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ContextInitOptions()
530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        : bind_generates_resource_client(true),
531c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          bind_generates_resource_service(true),
532c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          lose_context_when_out_of_memory(false) {}
533c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
534c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool bind_generates_resource_client;
535c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool bind_generates_resource_service;
536c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool lose_context_when_out_of_memory;
537c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  };
538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool Initialize(const ContextInitOptions& init_options) {
540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool success = true;
5416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
543c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    for (int i = 0; i < kNumTestContexts; i++) {
544c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      if (!test_contexts_[i].Initialize(
545c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              share_group_.get(),
546c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              init_options.bind_generates_resource_client,
5476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              init_options.bind_generates_resource_service,
548c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              init_options.lose_context_when_out_of_memory))
549c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        success = false;
550c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Default to test context 0.
553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gpu_control_ = test_contexts_[0].gpu_control_.get();
554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    helper_ = test_contexts_[0].helper_.get();
555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_ = test_contexts_[0].gl_.get();
557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    commands_ = test_contexts_[0].commands_;
558c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return success;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockClientCommandBuffer* command_buffer() const {
562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return test_contexts_[0].command_buffer_.get();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int GetNextToken() { return test_contexts_[0].GetNextToken(); }
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* GetPut() {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return helper_->GetSpace(0);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearCommands() {
572effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
573effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t MaxTransferBufferSize() {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return transfer_buffer_->MaxTransferBufferSize();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo GetExpectedMemory(size_t size) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return transfer_buffer_->GetExpectedMemory(size);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return transfer_buffer_->GetExpectedResultMemory(size);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the ProgramInfoManager. The manager will be owned
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by the ShareGroup.
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetProgramInfoManager(ProgramInfoManager* manager) {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gl_->share_group()->set_program_info_manager(manager);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int CheckError() {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectedMemoryInfo result =
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetExpectedResultMemory(sizeof(cmds::GetError::Result));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*command_buffer(), OnFlush())
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .RetiresOnSaturation();
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gl_->GetError();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const std::string& GetLastError() {
6045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return gl_->GetLastError();
6055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
6065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gl_->GetBucketContents(bucket_id, data);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestContext test_contexts_[kNumTestContexts];
612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<ShareGroup> share_group_;
614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MockClientGpuControl* gpu_control_;
615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GLES2CmdHelper* helper_;
616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MockTransferBuffer* transfer_buffer_;
617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GLES2Implementation* gl_;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferEntry* commands_;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLES2ImplementationTest::SetUp() {
622c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ContextInitOptions init_options;
623c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ASSERT_TRUE(Initialize(init_options));
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLES2ImplementationTest::TearDown() {
627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < kNumTestContexts; i++)
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    test_contexts_[i].TearDown();
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
631e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
632e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch protected:
633e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void SetUp() OVERRIDE {}
634e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
635e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE;
639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template <class ResApi>
641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void FlushGenerationTest() {
642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLuint id1, id2, id3;
643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Generate valid id.
645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl_, 1, &id1);
646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, 0u);
647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Delete id1 and generate id2.  id1 should not be reused.
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Delete(gl_, 1, &id1);
650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl_, 1, &id2);
651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id2, 0u);
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id2, id1);
653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Expect id1 reuse after Flush.
655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl_->Flush();
656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl_, 1, &id3);
657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(id3, id1);
658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ids should not be reused unless the |Deleting| context does a Flush()
661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // AND triggers a lazy release after that.
662a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template <class ResApi>
663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void CrossContextGenerationTest() {
664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLuint id1, id2, id3;
667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Delete, no flush on context 1.  No reuse.
669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl1, 1, &id1);
670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Delete(gl1, 1, &id1);
671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl1, 1, &id2);
672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, id2);
673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Flush context 2.  Still no reuse.
675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl2->Flush();
676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl2, 1, &id3);
677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, id3);
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id2, id3);
679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Flush on context 1, but no lazy release.  Still no reuse.
681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl1->Flush();
682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl2, 1, &id3);
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, id3);
684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Lazy release triggered by another Delete.  Should reuse id1.
686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Delete(gl1, 1, &id2);
687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl2, 1, &id3);
688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(id1, id3);
689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the Delete().  Tests an edge case regression.
693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template <class ResApi>
694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void CrossContextGenerationAutoFlushTest() {
695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GLuint id1, id2, id3;
698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Delete, no flush on context 1.  No reuse.
700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // By half filling the buffer, an internal flush is forced on the Delete().
701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl1, 1, &id1);
702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl1->helper()->Noop(kNumCommandEntries / 2);
703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Delete(gl1, 1, &id1);
704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl1, 1, &id2);
705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, id2);
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Flush context 2.  Still no reuse.
708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl2->Flush();
709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl2, 1, &id3);
710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, id3);
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id2, id3);
712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Flush on context 1, but no lazy release.  Still no reuse.
714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gl1->Flush();
715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl2, 1, &id3);
716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_NE(id1, id3);
717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Lazy release triggered by another Delete.  Should reuse id1.
719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Delete(gl1, 1, &id2);
720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ResApi::Gen(gl2, 1, &id3);
721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(id1, id3);
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLES2ImplementationStrictSharedTest::SetUp() {
726c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ContextInitOptions init_options;
727c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  init_options.bind_generates_resource_client = false;
728c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  init_options.bind_generates_resource_service = false;
729c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ASSERT_TRUE(Initialize(init_options));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GCC requires these declarations, but MSVC requires they not be present
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _MSC_VER
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint8 GLES2ImplementationTest::kInitialValue;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32 GLES2ImplementationTest::kNumCommandEntries;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t GLES2ImplementationTest::kTransferBufferSize;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxTextureSize;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxVaryingVectors;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxVertexAttribs;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kStartId;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kBuffersStartId;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kFramebuffersStartId;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kTexturesStartId;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kQueriesStartId;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint GLES2ImplementationTest::kVertexArraysStartId;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLES2ImplementationTest, Basic) {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(gl_->share_group() != NULL);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLES2ImplementationTest, GetBucketContents) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kBucketId = GLES2Implementation::kResultBucketId;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kTestSize = MaxTransferBufferSize() + 32;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8* expected_data = buf.get();
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 ii = 0; ii < kTestSize; ++ii) {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_data[ii] = ii * 3;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct Cmds {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::GetBucketStart get_bucket_start;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetToken set_token1;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::GetBucketData get_bucket_data;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetToken set_token2;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketSize set_bucket_size2;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo mem2 = GetExpectedMemory(
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kTestSize - MaxTransferBufferSize());
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cmds expected;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.get_bucket_start.Init(
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBucketId, result1.id, result1.offset,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MaxTransferBufferSize(), mem1.id, mem1.offset);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_token1.Init(GetNextToken());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.get_bucket_data.Init(
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBucketId, MaxTransferBufferSize(),
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_bucket_size2.Init(kBucketId, 0);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_token2.Init(GetNextToken());
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*command_buffer(), OnFlush())
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(DoAll(
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SetMemory(result1.ptr, kTestSize),
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SetMemoryFromArray(
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              mem1.ptr, expected_data, MaxTransferBufferSize())))
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(SetMemoryFromArray(
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          mem2.ptr, expected_data + MaxTransferBufferSize(),
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kTestSize - MaxTransferBufferSize()))
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int8> data;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetBucketContents(kBucketId, &data);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(kTestSize, data.size());
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct Cmds {
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cmds::GetShaderPrecisionFormat cmd;
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef cmds::GetShaderPrecisionFormat::Result Result;
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first call for mediump should trigger a command buffer request.
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint range1[2] = {0, 0};
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint precision1 = 0;
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Cmds expected1;
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected1.cmd.Init(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     client_result1.id, client_result1.offset);
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Result server_result1 = {true, 14, 14, 10};
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*command_buffer(), OnFlush())
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(SetMemory(client_result1.ptr, server_result1))
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .RetiresOnSaturation();
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                range1, &precision1);
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const void* commands2 = GetPut();
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(commands_, commands2);
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(range1[0], 14);
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(range1[1], 14);
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(precision1, 10);
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second call for mediump should use the cached value and avoid
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // triggering a command buffer request, so we do not expect a call to
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // OnFlush() here. We do expect the results to be correct though.
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint range2[2] = {0, 0};
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint precision2 = 0;
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                range2, &precision2);
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const void* commands3 = GetPut();
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(commands2, commands3);
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(range2[0], 14);
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(range2[1], 14);
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(precision2, 10);
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we then make a request for highp, we should get another command
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // buffer request since it hasn't been cached yet.
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint range3[2] = {0, 0};
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint precision3 = 0;
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Cmds expected3;
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected3.cmd.Init(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     result3.id, result3.offset);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Result result3_source = {true, 62, 62, 16};
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*command_buffer(), OnFlush())
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(SetMemory(result3.ptr, result3_source))
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .RetiresOnSaturation();
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                range3, &precision3);
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const void* commands4 = GetPut();
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(commands3, commands4);
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(range3[0], 62);
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(range3[1], 62);
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(precision3, 16);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLES2ImplementationTest, ShaderSource) {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kBucketId = GLES2Implementation::kResultBucketId;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kShaderId = 456;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kString1 = "foobar";
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kString2 = "barfoo";
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kString1Size = strlen(kString1);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kString2Size = strlen(kString2);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kString3Size = 1;  // Want the NULL;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kPaddedString1Size =
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transfer_buffer_->RoundToAlignment(kString1Size);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kPaddedString2Size =
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transfer_buffer_->RoundToAlignment(kString2Size);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kPaddedString3Size =
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transfer_buffer_->RoundToAlignment(kString3Size);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct Cmds {
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketSize set_bucket_size;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketData set_bucket_data1;
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetToken set_token1;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketData set_bucket_data2;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetToken set_token2;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketData set_bucket_data3;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetToken set_token3;
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cmds::ShaderSourceBucket shader_source_bucket;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketSize clear_bucket_size;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cmds expected;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_bucket_size.Init(kBucketId, kSourceSize);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_bucket_data1.Init(
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBucketId, 0, kString1Size, mem1.id, mem1.offset);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_token1.Init(GetNextToken());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_bucket_data2.Init(
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_token2.Init(GetNextToken());
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_bucket_data3.Init(
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBucketId, kString1Size + kString2Size,
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kString3Size, mem3.id, mem3.offset);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_token3.Init(GetNextToken());
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.shader_source_bucket.Init(kShaderId, kBucketId);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.clear_bucket_size.Init(kBucketId, 0);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* strings[] = {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kString1,
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kString2,
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gl_->ShaderSource(kShaderId, 2, strings, NULL);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLES2ImplementationTest, GetShaderSource) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kBucketId = GLES2Implementation::kResultBucketId;
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kShaderId = 456;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Str7 kString = {"foobar"};
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kBad = 0x12;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct Cmds {
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketSize set_bucket_size1;
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cmds::GetShaderSource get_shader_source;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::GetBucketStart get_bucket_start;
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetToken set_token1;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cmd::SetBucketSize set_bucket_size2;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cmds expected;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.set_bucket_size1.Init(kBucketId, 0);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.get_shader_source.Init(kShaderId, kBucketId);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.get_bucket_start.Init(
949