1e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li/*
2e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** Copyright 2011, The Android Open Source Project
3e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li **
4e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** Licensed under the Apache License, Version 2.0 (the "License");
5e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** you may not use this file except in compliance with the License.
6e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** You may obtain a copy of the License at
7e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li **
8e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li **     http://www.apache.org/licenses/LICENSE-2.0
9e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li **
10e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** Unless required by applicable law or agreed to in writing, software
11e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** distributed under the License is distributed on an "AS IS" BASIS,
12e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** See the License for the specific language governing permissions and
14e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li ** limitations under the License.
15e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li */
16e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
17e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li#include <sys/socket.h>
18e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li#include <sys/ioctl.h>
19e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
20e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li#include "header.h"
21e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li#include "gtest/gtest.h"
22e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li#include "hooks.h"
23e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
24e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Linamespace android
25e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
26e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Liextern int serverSock, clientSock;
27e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li};
28e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
29e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Livoid * glNoop();
30e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
31e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Liclass SocketContextTest : public ::testing::Test
32e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
33e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Liprotected:
347adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    DbgContext* dbg;
35e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    gl_hooks_t hooks;
36e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    int sock;
37e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    char * buffer;
38e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    unsigned int bufferSize;
39e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
40e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    SocketContextTest() : sock(-1) {
41e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
42e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
43e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    virtual ~SocketContextTest() {
44e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
45e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
46e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    virtual void SetUp() {
47575e01c6c767274a9581e07290aa41e928c643ebMathias Agopian        dbg = new DbgContext(1, &hooks, 32);
487adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian        ASSERT_TRUE(dbg != NULL);
49e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
50e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            ((void **)&hooks)[i] = (void *)glNoop;
51e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
52e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        int socks[2] = {-1, -1};
53e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, socks));
54e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        clientSock = socks[0];
55e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        sock = socks[1];
56e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
57e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        bufferSize = 128;
58e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        buffer = new char [128];
59e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_NE((char *)NULL, buffer);
60e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
61e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
62e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    virtual void TearDown() {
63e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        close(sock);
64e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        close(clientSock);
65e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        clientSock = -1;
66e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        delete buffer;
67e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
68e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
69e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    void Write(glesv2debugger::Message & msg) const {
707adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian        msg.set_context_id((int)dbg);
71e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        msg.set_type(msg.Response);
72e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_context_id());
73e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_function());
74e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_type());
75e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_expect_response());
76e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static std::string str;
77e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        msg.SerializeToString(&str);
78e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        const uint32_t len = str.length();
79e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(sizeof(len), send(sock, &len, sizeof(len), 0));
80e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(str.length(), send(sock, str.data(), str.length(), 0));
81e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
82e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
83e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    void Read(glesv2debugger::Message & msg) {
84e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        int available = 0;
85e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(0, ioctl(sock, FIONREAD, &available));
86e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_GT(available, 0);
87e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        uint32_t len = 0;
88e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(sizeof(len), recv(sock, &len, sizeof(len), 0));
89e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        if (len > bufferSize) {
90e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            bufferSize = len;
91e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            buffer = new char[bufferSize];
9231918ccae9341bca169c58035482c68de2d27e22David Li            ASSERT_TRUE(buffer != NULL);
93e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
94e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(len, recv(sock, buffer, len, 0));
95e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        msg.Clear();
96e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        msg.ParseFromArray(buffer, len);
97e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_context_id());
98e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_function());
99e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_type());
100e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_TRUE(msg.has_expect_response());
101e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
102e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
103e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    void CheckNoAvailable() {
104e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        int available = 0;
105e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(0, ioctl(sock, FIONREAD, &available));
106e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        ASSERT_EQ(available, 0);
107e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    }
108e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li};
109e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
110e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid LiTEST_F(SocketContextTest, MessageLoopSkip)
111e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
112e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int arg0 = 45;
113e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const float arg7 = -87.2331f;
114e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int arg8 = -3;
115e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int * ret = (int *)870;
116e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
117e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    struct Caller : public FunctionCall {
118e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
119e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            msg.set_arg0(arg0);
120e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            msg.set_arg7((int &)arg7);
121e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            msg.set_arg8(arg8);
122e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return ret;
123e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
124e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    } caller;
125e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    glesv2debugger::Message msg, read, cmd;
1267adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    dbg->expectResponse.Bit(msg.glFinish, true);
127e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
128e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.SKIP);
129e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(false);
130e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
131e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
132e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_NE(ret, MessageLoop(caller, msg, msg.glFinish));
133e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
134e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
135e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glFinish, read.function());
136e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.BeforeCall, read.type());
137e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_NE(arg0, read.arg0());
138e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_NE((int &)arg7, read.arg7());
139e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_NE(arg8, read.arg8());
140e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
141e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    CheckNoAvailable();
142e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li}
143e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
144e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid LiTEST_F(SocketContextTest, MessageLoopContinue)
145e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
146e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int arg0 = GL_FRAGMENT_SHADER;
147e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int ret = -342;
148e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    struct Caller : public FunctionCall {
149e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
150e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            msg.set_ret(ret);
151e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return (int *)ret;
152e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
153e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    } caller;
154e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    glesv2debugger::Message msg, read, cmd;
1557adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    dbg->expectResponse.Bit(msg.glCreateShader, true);
156e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
157e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.CONTINUE);
158e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(false); // MessageLoop should automatically skip after continue
159e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
160e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
161e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    msg.set_arg0(arg0);
162e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateShader));
163e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
164e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
165e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateShader, read.function());
166e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.BeforeCall, read.type());
167e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(arg0, read.arg0());
168e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
169e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
170e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateShader, read.function());
171e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterCall, read.type());
172e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(ret, read.ret());
173e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
174e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    CheckNoAvailable();
175e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li}
176e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
177e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid LiTEST_F(SocketContextTest, MessageLoopGenerateCall)
178e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
179e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int ret = -342;
180e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static unsigned int createShader, createProgram;
181e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    createShader = 0;
182e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    createProgram = 0;
183e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    struct Caller : public FunctionCall {
184e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
185e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            const int r = (int)_c->glCreateProgram();
186e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            msg.set_ret(r);
187e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return (int *)r;
188e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
189e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static GLuint CreateShader(const GLenum type) {
190e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            createShader++;
191e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return type;
192e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
193e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static GLuint CreateProgram() {
194e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            createProgram++;
195e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return ret;
196e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
197e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    } caller;
198e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    glesv2debugger::Message msg, read, cmd;
199e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glCreateShader = caller.CreateShader;
200e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glCreateProgram = caller.CreateProgram;
2017adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    dbg->expectResponse.Bit(msg.glCreateProgram, true);
202e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
203e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.glCreateShader);
204e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg0(GL_FRAGMENT_SHADER);
205e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(true);
206e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
207e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
208e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.Clear();
209e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.CONTINUE);
210e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(true);
211e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
212e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
213e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.glCreateShader);
214e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg0(GL_VERTEX_SHADER);
215e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(false); // MessageLoop should automatically skip afterwards
216e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
217e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
218e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateProgram));
219e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
220e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
221e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateProgram, read.function());
222e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.BeforeCall, read.type());
223e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
224e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
225e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateShader, read.function());
226e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterGeneratedCall, read.type());
227e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(GL_FRAGMENT_SHADER, read.ret());
228e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
229e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
230e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateProgram, read.function());
231e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterCall, read.type());
232e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(ret, read.ret());
233e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
234e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
235e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateShader, read.function());
236e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterGeneratedCall, read.type());
237e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(GL_VERTEX_SHADER, read.ret());
238e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
239e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(2, createShader);
240e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(1, createProgram);
241e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
242e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    CheckNoAvailable();
243e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li}
244e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
245e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid LiTEST_F(SocketContextTest, MessageLoopSetProp)
246e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
247e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int ret = -342;
248e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static unsigned int createShader, createProgram;
249e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    createShader = 0;
250e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    createProgram = 0;
251e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    struct Caller : public FunctionCall {
252e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
253e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            const int r = (int)_c->glCreateProgram();
254e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            msg.set_ret(r);
255e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return (int *)r;
256e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
257e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static GLuint CreateShader(const GLenum type) {
258e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            createShader++;
259e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return type;
260e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
261e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static GLuint CreateProgram() {
262e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            createProgram++;
263e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            return ret;
264e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
265e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    } caller;
266e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    glesv2debugger::Message msg, read, cmd;
267e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glCreateShader = caller.CreateShader;
268e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glCreateProgram = caller.CreateProgram;
2697adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    dbg->expectResponse.Bit(msg.glCreateProgram, false);
270e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
271e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.SETPROP);
272e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_prop(cmd.ExpectResponse);
273e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg0(cmd.glCreateProgram);
274e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg1(true);
275e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(true);
276e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
277e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
278e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.Clear();
279e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.glCreateShader);
280e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg0(GL_FRAGMENT_SHADER);
281e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(true);
282e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
283e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
284e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.SETPROP);
285e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_prop(cmd.CaptureDraw);
286e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg0(819);
287e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(true);
288e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
289e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
290e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.Clear();
291e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.CONTINUE);
292e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(true);
293e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
294e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
295e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_function(cmd.glCreateShader);
296e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_arg0(GL_VERTEX_SHADER);
297e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    cmd.set_expect_response(false); // MessageLoop should automatically skip afterwards
298e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Write(cmd);
299e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
300e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateProgram));
301e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
3027adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    EXPECT_TRUE(dbg->expectResponse.Bit(msg.glCreateProgram));
3037adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    EXPECT_EQ(819, dbg->captureDraw);
304e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
305e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
306e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateProgram, read.function());
307e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.BeforeCall, read.type());
308e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
309e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
310e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateShader, read.function());
311e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterGeneratedCall, read.type());
312e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(GL_FRAGMENT_SHADER, read.ret());
313e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
314e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
315e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateProgram, read.function());
316e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterCall, read.type());
317e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(ret, read.ret());
318e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
319e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
320e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCreateShader, read.function());
321e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterGeneratedCall, read.type());
322e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(GL_VERTEX_SHADER, read.ret());
323e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
324e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(2, createShader);
325e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(1, createProgram);
326e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
327e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    CheckNoAvailable();
328e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li}
329e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
330e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid LiTEST_F(SocketContextTest, TexImage2D)
331e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
332e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLenum _target = GL_TEXTURE_2D;
333e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLint _level = 1, _internalformat = GL_RGBA;
334e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLsizei _width = 2, _height = 2;
335e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLint _border = 333;
336e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLenum _format = GL_RGB, _type = GL_UNSIGNED_SHORT_5_6_5;
337e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const short _pixels [_width * _height] = {11, 22, 33, 44};
338e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static unsigned int texImage2D;
339e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    texImage2D = 0;
340e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
341e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    struct Caller {
342e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static void TexImage2D(GLenum target, GLint level, GLint internalformat,
343e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                               GLsizei width, GLsizei height, GLint border,
344e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                               GLenum format, GLenum type, const GLvoid* pixels) {
345e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_target, target);
346e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_level, level);
347e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_internalformat, internalformat);
348e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_width, width);
349e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_height, height);
350e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_border, border);
351e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_format, format);
352e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_type, type);
353e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(0, memcmp(_pixels, pixels, sizeof(_pixels)));
354e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            texImage2D++;
355e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
356e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    } caller;
357e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    glesv2debugger::Message msg, read, cmd;
358e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glTexImage2D = caller.TexImage2D;
3597adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    dbg->expectResponse.Bit(msg.glTexImage2D, false);
360e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
361e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Debug_glTexImage2D(_target, _level, _internalformat, _width, _height, _border,
362e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                       _format, _type, _pixels);
363e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(1, texImage2D);
364e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
365e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
366e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glTexImage2D, read.function());
367e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.BeforeCall, read.type());
368e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_target, read.arg0());
369e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_level, read.arg1());
370e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_internalformat, read.arg2());
371e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_width, read.arg3());
372e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_height, read.arg4());
373e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_border, read.arg5());
374e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_format, read.arg6());
375e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_type, read.arg7());
376e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
377e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_TRUE(read.has_data());
378e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    uint32_t dataLen = 0;
3797adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    const unsigned char * data = dbg->Decompress(read.data().data(),
380e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                                 read.data().length(), &dataLen);
381e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(sizeof(_pixels), dataLen);
382e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    if (sizeof(_pixels) == dataLen)
383e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        EXPECT_EQ(0, memcmp(_pixels, data, sizeof(_pixels)));
384e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
385e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
386e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glTexImage2D, read.function());
387e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterCall, read.type());
388e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
389e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    CheckNoAvailable();
390e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li}
391e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
392e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid LiTEST_F(SocketContextTest, CopyTexImage2D)
393e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li{
394e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLenum _target = GL_TEXTURE_2D;
395e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLint _level = 1, _internalformat = GL_RGBA;
396e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLint _x = 9, _y = 99;
397e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLsizei _width = 2, _height = 3;
398e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const GLint _border = 333;
399e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static const int _pixels [_width * _height] = {11, 22, 33, 44, 55, 66};
400e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    static unsigned int copyTexImage2D, readPixels;
401e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    copyTexImage2D = 0, readPixels = 0;
402e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
403e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    struct Caller {
404e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
405e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                                   GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
406e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_target, target);
407e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_level, level);
408e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_internalformat, internalformat);
409e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_x, x);
410e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_y, y);
411e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_width, width);
412e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_height, height);
413e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_border, border);
414e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            copyTexImage2D++;
415e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
416e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        static void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
417e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                               GLenum format, GLenum type, GLvoid* pixels) {
418e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_x, x);
419e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_y, y);
420e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_width, width);
421e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(_height, height);
422e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(GL_RGBA, format);
423e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            EXPECT_EQ(GL_UNSIGNED_BYTE, type);
42431918ccae9341bca169c58035482c68de2d27e22David Li            ASSERT_TRUE(pixels != NULL);
425e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            memcpy(pixels, _pixels, sizeof(_pixels));
426e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li            readPixels++;
427e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        }
428e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    } caller;
429e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    glesv2debugger::Message msg, read, cmd;
430e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glCopyTexImage2D = caller.CopyTexImage2D;
431e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    hooks.gl.glReadPixels = caller.ReadPixels;
4327adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    dbg->expectResponse.Bit(msg.glCopyTexImage2D, false);
433e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
434e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Debug_glCopyTexImage2D(_target, _level, _internalformat, _x, _y, _width, _height,
435e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                           _border);
436e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    ASSERT_EQ(1, copyTexImage2D);
437e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    ASSERT_EQ(1, readPixels);
438e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
439e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
440e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCopyTexImage2D, read.function());
441e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.BeforeCall, read.type());
442e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_target, read.arg0());
443e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_level, read.arg1());
444e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_internalformat, read.arg2());
445e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_x, read.arg3());
446e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_y, read.arg4());
447e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_width, read.arg5());
448e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_height, read.arg6());
449e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(_border, read.arg7());
450e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
451e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_TRUE(read.has_data());
452e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.ReferencedImage, read.data_type());
453e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(GL_RGBA, read.pixel_format());
454e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(GL_UNSIGNED_BYTE, read.pixel_type());
455e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    uint32_t dataLen = 0;
4567adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7cMathias Agopian    unsigned char * const data = dbg->Decompress(read.data().data(),
457e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li                                 read.data().length(), &dataLen);
458e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    ASSERT_EQ(sizeof(_pixels), dataLen);
459e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    for (unsigned i = 0; i < sizeof(_pixels) / sizeof(*_pixels); i++)
460e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li        EXPECT_EQ(_pixels[i], ((const int *)data)[i]) << "xor with 0 ref is identity";
461e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    free(data);
462e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
463e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    Read(read);
464e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.glCopyTexImage2D, read.function());
465e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    EXPECT_EQ(read.AfterCall, read.type());
466e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li
467e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li    CheckNoAvailable();
468e9f619f03b0e98d1ff7ff0d7333fb502ec5bc54bDavid Li}
469