Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 434063: Merged in recent changes to command buffer code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A class to emluate GLES2 over command buffers. 5 // A class to emluate GLES2 over command buffers.
6 6
7 #include "gpu/command_buffer/client/gles2_implementation.h" 7 #include "gpu/command_buffer/client/gles2_implementation.h"
8 // TODO(gman): remove when all functions have been implemented. 8 // TODO(gman): remove when all functions have been implemented.
9 #include "gpu/command_buffer/client/gles2_implementation_gen.h" 9 #include "gpu/command_buffer/client/gles2_implementation_gen.h"
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
11 11
12 namespace command_buffer { 12 namespace command_buffer {
13 namespace gles2 { 13 namespace gles2 {
14 14
15 GLES2Implementation::GLES2Implementation( 15 GLES2Implementation::GLES2Implementation(
16 GLES2CmdHelper* helper, 16 GLES2CmdHelper* helper,
17 size_t transfer_buffer_size,
17 void* transfer_buffer, 18 void* transfer_buffer,
18 int transfer_buffer_id) 19 int32 transfer_buffer_id)
19 : util_(0), // TODO(gman): Get real number of compressed texture formats. 20 : util_(0), // TODO(gman): Get real number of compressed texture formats.
20 helper_(helper), 21 helper_(helper),
21 shared_memory_(transfer_buffer, transfer_buffer_id), 22 transfer_buffer_(transfer_buffer_size, helper, transfer_buffer),
23 transfer_buffer_id_(transfer_buffer_id),
22 pack_alignment_(4), 24 pack_alignment_(4),
23 unpack_alignment_(4) { 25 unpack_alignment_(4) {
26 // Eat 1 id so we start at 1 instead of 0.
27 GLuint eat;
28 MakeIds(1, &eat);
29 // Allocate space for simple GL results.
30 result_buffer_ = transfer_buffer_.Alloc(kMaxSizeOfSimpleResult);
31 result_shm_offset_ = transfer_buffer_.GetOffset(result_buffer_);
24 } 32 }
25 33
26 void GLES2Implementation::MakeIds(GLsizei n, GLuint* ids) { 34 void GLES2Implementation::MakeIds(GLsizei n, GLuint* ids) {
27 for (GLsizei ii = 0; ii < n; ++ii) { 35 for (GLsizei ii = 0; ii < n; ++ii) {
28 ids[ii] = id_allocator_.AllocateID(); 36 ids[ii] = id_allocator_.AllocateID();
29 } 37 }
30 } 38 }
31 39
32 void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) { 40 void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) {
33 for (GLsizei ii = 0; ii < n; ++ii) { 41 for (GLsizei ii = 0; ii < n; ++ii) {
34 id_allocator_.FreeID(ids[ii]); 42 id_allocator_.FreeID(ids[ii]);
35 } 43 }
36 } 44 }
37 45
46 void GLES2Implementation::WaitForCmd() {
47 int32 token = helper_->InsertToken();
48 helper_->WaitForToken(token);
49 }
50
38 void GLES2Implementation::DrawElements( 51 void GLES2Implementation::DrawElements(
39 GLenum mode, GLsizei count, GLenum type, const void* indices) { 52 GLenum mode, GLsizei count, GLenum type, const void* indices) {
40 helper_->DrawElements(mode, count, type, reinterpret_cast<GLuint>(indices)); 53 helper_->DrawElements(mode, count, type, reinterpret_cast<GLuint>(indices));
41 } 54 }
42 55
56 GLint GLES2Implementation::GetAttribLocation(
57 GLuint program, const char* name) {
58 helper_->GetAttribLocationImmediate(
59 program, name, result_shm_id(), result_shm_offset());
60 WaitForCmd();
61 return GetResultAs<GLint>();
62 }
63
64 GLint GLES2Implementation::GetUniformLocation(
65 GLuint program, const char* name) {
66 helper_->GetUniformLocationImmediate(
67 program, name, result_shm_id(), result_shm_offset());
68 WaitForCmd();
69 return GetResultAs<GLint>();
70 }
71
72 void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
73 switch (pname) {
74 case GL_PACK_ALIGNMENT:
75 pack_alignment_ = param;
76 break;
77 case GL_UNPACK_ALIGNMENT:
78 unpack_alignment_ = param;
79 break;
80 default:
81 break;
82 }
83 helper_->PixelStorei(pname, param);
84 }
85
86
43 void GLES2Implementation::VertexAttribPointer( 87 void GLES2Implementation::VertexAttribPointer(
44 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, 88 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
45 const void* ptr) { 89 const void* ptr) {
46 helper_->VertexAttribPointer(index, size, type, normalized, stride, 90 helper_->VertexAttribPointer(index, size, type, normalized, stride,
47 reinterpret_cast<GLuint>(ptr)); 91 reinterpret_cast<GLuint>(ptr));
48 } 92 }
49 93
50 void GLES2Implementation::ShaderSource( 94 void GLES2Implementation::ShaderSource(
51 GLuint shader, GLsizei count, const char** string, const GLint* length) { 95 GLuint shader, GLsizei count, const char** source, const GLint* length) {
52 // TODO(gman): change to use buckets and check that there is enough room. 96 // TODO(gman): change to use buckets and check that there is enough room.
53 uint32* offsets = shared_memory_.GetAddressAs<uint32*>(0);
54 char* strings = reinterpret_cast<char*>(offsets + count);
55 97
98 // Compute the total size.
99 uint32 total_size = count * sizeof(total_size);
100 for (GLsizei ii = 0; ii < count; ++ii) {
101 total_size += length ? length[ii] : strlen(source[ii]);
102 }
103
104 // Create string table in transfer buffer.
105 char* strings = transfer_buffer_.AllocTyped<char>(total_size);
106 uint32* offsets = reinterpret_cast<uint32*>(strings);
56 uint32 offset = count * sizeof(*offsets); 107 uint32 offset = count * sizeof(*offsets);
57 for (GLsizei ii = 0; ii < count; ++ii) { 108 for (GLsizei ii = 0; ii < count; ++ii) {
58 uint32 len = length ? length[ii] : strlen(string[ii]); 109 uint32 len = length ? length[ii] : strlen(source[ii]);
59 memcpy(strings + offset, string[ii], len); 110 memcpy(strings + offset, source[ii], len);
60 offset += len; 111 offset += len;
61 offsets[ii] = offset; 112 offsets[ii] = offset;
62 } 113 }
63 114
64 helper_->ShaderSource(shader, count, shared_memory_.GetId(), 0, offset); 115 helper_->ShaderSource(shader, count,
65 // TODO(gman): Should insert token but not wait until we need shared memory 116 transfer_buffer_id_,
66 // again. Really, I should implement a shared memory manager that puts 117 transfer_buffer_.GetOffset(strings), offset);
67 // things in the next unused part of shared memory and only blocks 118 transfer_buffer_.FreePendingToken(strings, helper_->InsertToken());
68 // when it needs more memory.
69 int32 token = helper_->InsertToken();
70 helper_->WaitForToken(token);
71 } 119 }
72 120
73 void GLES2Implementation::BufferData( 121 void GLES2Implementation::BufferData(
74 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { 122 GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
75 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared 123 // NOTE: Should this be optimized for the case where we can call BufferData
76 // memory. 124 // with the actual data in the case of our transfer buffer being big
77 memcpy(shared_memory_.GetAddress(0), data, size); 125 // enough?
78 helper_->BufferData(target, size, shared_memory_.GetId(), 0, usage); 126 helper_->BufferData(target, size, 0, 0, usage);
79 int32 token = helper_->InsertToken(); 127 if (data != NULL) {
80 helper_->WaitForToken(token); 128 BufferSubData(target, 0, size, data);
129 }
81 } 130 }
82 131
83 void GLES2Implementation::BufferSubData( 132 void GLES2Implementation::BufferSubData(
84 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { 133 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
85 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared 134 const int8* source = static_cast<const int8*>(data);
86 // memory. 135 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
87 memcpy(shared_memory_.GetAddress(0), data, size); 136 while (size) {
88 helper_->BufferSubData(target, offset, size, shared_memory_.GetId(), 0); 137 GLsizeiptr part_size = std::min(size, max_size);
89 int32 token = helper_->InsertToken(); 138 void* buffer = transfer_buffer_.Alloc(part_size);
90 helper_->WaitForToken(token); 139 memcpy(buffer, source, part_size);
140 helper_->BufferSubData(target, offset, part_size,
141 transfer_buffer_id_,
142 transfer_buffer_.GetOffset(buffer));
143 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
144 offset += part_size;
145 source += part_size;
146 size -= part_size;
147 }
91 } 148 }
92 149
93 void GLES2Implementation::CompressedTexImage2D( 150 void GLES2Implementation::CompressedTexImage2D(
94 GLenum target, GLint level, GLenum internalformat, GLsizei width, 151 GLenum target, GLint level, GLenum internalformat, GLsizei width,
95 GLsizei height, GLint border, GLsizei imageSize, const void* data) { 152 GLsizei height, GLint border, GLsizei image_size, const void* data) {
96 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared 153 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
97 // memory. 154 // memory.
98 memcpy(shared_memory_.GetAddress(0), data, imageSize); 155 DCHECK_LE(image_size,
156 static_cast<GLsizei>(
157 transfer_buffer_.GetLargestFreeOrPendingSize()));
158 void* buffer = transfer_buffer_.Alloc(image_size);
159 memcpy(buffer, data, image_size);
99 helper_->CompressedTexImage2D( 160 helper_->CompressedTexImage2D(
100 target, level, internalformat, width, height, border, imageSize, 161 target, level, internalformat, width, height, border, image_size,
101 shared_memory_.GetId(), 0); 162 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
102 int32 token = helper_->InsertToken(); 163 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
103 helper_->WaitForToken(token);
104 } 164 }
105 165
106 void GLES2Implementation::CompressedTexSubImage2D( 166 void GLES2Implementation::CompressedTexSubImage2D(
107 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, 167 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
108 GLsizei height, GLenum format, GLsizei imageSize, const void* data) { 168 GLsizei height, GLenum format, GLsizei image_size, const void* data) {
109 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared 169 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
110 // memory. 170 // memory.
111 memcpy(shared_memory_.GetAddress(0), data, imageSize); 171 DCHECK_LE(image_size,
172 static_cast<GLsizei>(
173 transfer_buffer_.GetLargestFreeOrPendingSize()));
174 void* buffer = transfer_buffer_.Alloc(image_size);
175 memcpy(buffer, data, image_size);
112 helper_->CompressedTexSubImage2D( 176 helper_->CompressedTexSubImage2D(
113 target, level, xoffset, yoffset, width, height, format, imageSize, 177 target, level, xoffset, yoffset, width, height, format, image_size,
114 shared_memory_.GetId(), 0); 178 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
115 int32 token = helper_->InsertToken(); 179 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
116 helper_->WaitForToken(token);
117 } 180 }
118 181
119 void GLES2Implementation::TexImage2D( 182 void GLES2Implementation::TexImage2D(
120 GLenum target, GLint level, GLint internalformat, GLsizei width, 183 GLenum target, GLint level, GLint internalformat, GLsizei width,
121 GLsizei height, GLint border, GLenum format, GLenum type, 184 GLsizei height, GLint border, GLenum format, GLenum type,
122 const void* pixels) { 185 const void* pixels) {
123 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
124 // memory.
125 uint32 pixels_size = GLES2Util::ComputeImageDataSize(
126 width, height, format, type, unpack_alignment_);
127 memcpy(shared_memory_.GetAddress(0), pixels, pixels_size);
128 helper_->TexImage2D( 186 helper_->TexImage2D(
129 target, level, internalformat, width, height, border, format, type, 187 target, level, internalformat, width, height, border, format, type, 0, 0);
130 shared_memory_.GetId(), 0); 188 if (pixels) {
131 int32 token = helper_->InsertToken(); 189 TexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
132 helper_->WaitForToken(token); 190 }
133 } 191 }
134 192
135 void GLES2Implementation::TexSubImage2D( 193 void GLES2Implementation::TexSubImage2D(
136 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, 194 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
137 GLsizei height, GLenum format, GLenum type, const void* pixels) { 195 GLsizei height, GLenum format, GLenum type, const void* pixels) {
138 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared 196 const int8* source = static_cast<const int8*>(pixels);
139 // memory. 197 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
140 uint32 pixels_size = GLES2Util::ComputeImageDataSize( 198
141 width, height, format, type, unpack_alignment_); 199 GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize(
142 memcpy(shared_memory_.GetAddress(0), pixels, pixels_size); 200 width, 1, format, type, unpack_alignment_);
143 helper_->TexSubImage2D( 201 GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize(
144 target, level, xoffset, yoffset, width, height, format, type, 202 width, 2, format, type, unpack_alignment_) - unpadded_row_size;
145 shared_memory_.GetId(), 0); 203
146 int32 token = helper_->InsertToken(); 204 if (padded_row_size <= max_size) {
147 helper_->WaitForToken(token); 205 // Transfer by rows.
206 GLint max_rows = max_size / padded_row_size;
207 while (height) {
208 GLint num_rows = std::min(height, max_rows);
209 GLsizeiptr part_size = num_rows * padded_row_size;
210 void* buffer = transfer_buffer_.Alloc(part_size);
211 memcpy(buffer, source, part_size);
212 helper_->TexSubImage2D(
213 target, level, xoffset, yoffset, width, num_rows, format, type,
214 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
215 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
216 yoffset += num_rows;
217 source += part_size;
218 height -= num_rows;
219 }
220 } else {
221 // Transfer by sub rows. Beacuse GL has no maximum texture dimensions.
222 GLsizeiptr element_size = GLES2Util::ComputeImageDataSize(
223 1, 1, format, type, unpack_alignment_);
224 max_size -= max_size % element_size;
225 GLint max_sub_row_pixels = max_size / element_size;
226 for (; height; --height) {
227 GLint temp_width = width;
228 GLint temp_xoffset = xoffset;
229 const int8* row_source = source;
230 while (temp_width) {
231 GLint num_pixels = std::min(width, max_sub_row_pixels);
232 GLsizeiptr part_size = num_pixels * element_size;
233 void* buffer = transfer_buffer_.Alloc(part_size);
234 memcpy(buffer, row_source, part_size);
235 helper_->TexSubImage2D(
236 target, level, temp_xoffset, yoffset, temp_width, 1, format, type,
237 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
238 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
239 row_source += part_size;
240 temp_xoffset += num_pixels;
241 temp_width -= num_pixels;
242 }
243 ++yoffset;
244 source += padded_row_size;
245 }
246 }
148 } 247 }
149 248
150 249
151 } // namespace gles2 250 } // namespace gles2
152 } // namespace command_buffer 251 } // namespace command_buffer
153 252
154 253
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.h ('k') | gpu/command_buffer/client/gles2_implementation_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698