OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 template <typename MANAGER_TYPE, typename OBJECT_TYPE> | 176 template <typename MANAGER_TYPE, typename OBJECT_TYPE> |
177 GLuint GetClientId(const MANAGER_TYPE* manager, const OBJECT_TYPE* object) { | 177 GLuint GetClientId(const MANAGER_TYPE* manager, const OBJECT_TYPE* object) { |
178 DCHECK(manager); | 178 DCHECK(manager); |
179 GLuint client_id = 0; | 179 GLuint client_id = 0; |
180 if (object) { | 180 if (object) { |
181 manager->GetClientId(object->service_id(), &client_id); | 181 manager->GetClientId(object->service_id(), &client_id); |
182 } | 182 } |
183 return client_id; | 183 return client_id; |
184 } | 184 } |
185 | 185 |
| 186 template <typename OBJECT_TYPE> |
| 187 GLuint GetServiceId(const OBJECT_TYPE* object) { |
| 188 return object ? object->service_id() : 0; |
| 189 } |
| 190 |
186 struct Vec4f { | 191 struct Vec4f { |
187 explicit Vec4f(const Vec4& data) { | 192 explicit Vec4f(const Vec4& data) { |
188 data.GetValues(v); | 193 data.GetValues(v); |
189 } | 194 } |
190 | 195 |
191 GLfloat v[4]; | 196 GLfloat v[4]; |
192 }; | 197 }; |
193 | 198 |
194 } // namespace | 199 } // namespace |
195 | 200 |
(...skipping 8601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8797 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); | 8802 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); |
8798 } else { | 8803 } else { |
8799 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); | 8804 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); |
8800 } | 8805 } |
8801 if (!data) { | 8806 if (!data) { |
8802 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer", | 8807 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer", |
8803 "Unable to map memory for readback."); | 8808 "Unable to map memory for readback."); |
8804 return; | 8809 return; |
8805 } | 8810 } |
8806 memcpy(pixels, data, pixels_size); | 8811 memcpy(pixels, data, pixels_size); |
8807 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't | |
8808 // have to restore the state. | |
8809 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); | 8812 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); |
8810 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | 8813 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, |
| 8814 GetServiceId(state_.bound_pixel_pack_buffer.get())); |
8811 glDeleteBuffersARB(1, &buffer); | 8815 glDeleteBuffersARB(1, &buffer); |
8812 } | 8816 } |
8813 | 8817 |
8814 if (result != NULL) { | 8818 if (result != NULL) { |
8815 *result = true; | 8819 *result = true; |
8816 } | 8820 } |
8817 | 8821 |
8818 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 8822 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
8819 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 8823 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
8820 if ((channels_exist & 0x0008) == 0 && | 8824 if ((channels_exist & 0x0008) == 0 && |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8880 GLsizei height = c.height; | 8884 GLsizei height = c.height; |
8881 GLenum format = c.format; | 8885 GLenum format = c.format; |
8882 GLenum type = c.type; | 8886 GLenum type = c.type; |
8883 GLboolean async = static_cast<GLboolean>(c.async); | 8887 GLboolean async = static_cast<GLboolean>(c.async); |
8884 if (width < 0 || height < 0) { | 8888 if (width < 0 || height < 0) { |
8885 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); | 8889 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); |
8886 return error::kNoError; | 8890 return error::kNoError; |
8887 } | 8891 } |
8888 typedef cmds::ReadPixels::Result Result; | 8892 typedef cmds::ReadPixels::Result Result; |
8889 uint32 pixels_size; | 8893 uint32 pixels_size; |
| 8894 if (state_.bound_pixel_pack_buffer.get()) { |
| 8895 // TODO(zmo): Need to handle the case of reading into a PIXEL_PACK_BUFFER |
| 8896 // in ES3, including more pack parameters. For now, generate a GL error. |
| 8897 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels", |
| 8898 "ReadPixels to a pixel pack buffer isn't implemented"); |
| 8899 return error::kNoError; |
| 8900 } |
8890 if (!GLES2Util::ComputeImageDataSizes( | 8901 if (!GLES2Util::ComputeImageDataSizes( |
8891 width, height, 1, format, type, state_.pack_alignment, &pixels_size, | 8902 width, height, 1, format, type, state_.pack_alignment, &pixels_size, |
8892 NULL, NULL)) { | 8903 NULL, NULL)) { |
8893 return error::kOutOfBounds; | 8904 return error::kOutOfBounds; |
8894 } | 8905 } |
8895 void* pixels = GetSharedMemoryAs<void*>( | 8906 void* pixels = GetSharedMemoryAs<void*>( |
8896 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); | 8907 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); |
8897 if (!pixels) { | 8908 if (!pixels) { |
8898 return error::kOutOfBounds; | 8909 return error::kOutOfBounds; |
8899 } | 8910 } |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9067 memset(dst, 0, unpadded_row_size); | 9078 memset(dst, 0, unpadded_row_size); |
9068 | 9079 |
9069 // If the row is in range, copy it. | 9080 // If the row is in range, copy it. |
9070 if (ry >= 0 && ry < max_size.height() && read_width > 0) { | 9081 if (ry >= 0 && ry < max_size.height() && read_width > 0) { |
9071 glReadPixels( | 9082 glReadPixels( |
9072 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); | 9083 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); |
9073 } | 9084 } |
9074 dst += padded_row_size; | 9085 dst += padded_row_size; |
9075 } | 9086 } |
9076 } else { | 9087 } else { |
9077 if (async && features().use_async_readpixels) { | 9088 if (async && features().use_async_readpixels && |
| 9089 !state_.bound_pixel_pack_buffer.get()) { |
| 9090 // To simply the state tracking, we don't go down the async path if |
| 9091 // a PIXEL_PACK_BUFFER is bound (in which case the client can |
| 9092 // implement something similar on their own - all necessary functions |
| 9093 // should be exposed). |
9078 GLuint buffer = 0; | 9094 GLuint buffer = 0; |
9079 glGenBuffersARB(1, &buffer); | 9095 glGenBuffersARB(1, &buffer); |
9080 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); | 9096 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); |
9081 // For ANGLE client version 2, GL_STREAM_READ is not available. | 9097 // For ANGLE client version 2, GL_STREAM_READ is not available. |
9082 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ? | 9098 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ? |
9083 GL_STATIC_DRAW : GL_STREAM_READ; | 9099 GL_STATIC_DRAW : GL_STREAM_READ; |
9084 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); | 9100 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); |
9085 GLenum error = glGetError(); | 9101 GLenum error = glGetError(); |
9086 if (error == GL_NO_ERROR) { | 9102 if (error == GL_NO_ERROR) { |
| 9103 // No need to worry about ES3 pxiel pack parameters, because no |
| 9104 // PIXEL_PACK_BUFFER is bound, and all these settings haven't been |
| 9105 // sent to GL. |
9087 glReadPixels(x, y, width, height, format, type, 0); | 9106 glReadPixels(x, y, width, height, format, type, 0); |
9088 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( | 9107 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( |
9089 new FenceCallback())); | 9108 new FenceCallback())); |
9090 WaitForReadPixels(base::Bind(&GLES2DecoderImpl::FinishReadPixels, | 9109 WaitForReadPixels(base::Bind(&GLES2DecoderImpl::FinishReadPixels, |
9091 base::AsWeakPtr(this), c, buffer)); | 9110 base::AsWeakPtr(this), c, buffer)); |
9092 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | 9111 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
9093 return error::kNoError; | 9112 return error::kNoError; |
9094 } else { | 9113 } else { |
9095 // On error, unbind pack buffer and fall through to sync readpixels | 9114 // On error, unbind pack buffer and fall through to sync readpixels |
9096 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | 9115 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
(...skipping 11 matching lines...) Expand all Loading... |
9108 } | 9127 } |
9109 | 9128 |
9110 return error::kNoError; | 9129 return error::kNoError; |
9111 } | 9130 } |
9112 | 9131 |
9113 error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, | 9132 error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, |
9114 const void* cmd_data) { | 9133 const void* cmd_data) { |
9115 const gles2::cmds::PixelStorei& c = | 9134 const gles2::cmds::PixelStorei& c = |
9116 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data); | 9135 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data); |
9117 GLenum pname = c.pname; | 9136 GLenum pname = c.pname; |
9118 GLenum param = c.param; | 9137 GLint param = c.param; |
9119 if (!validators_->pixel_store.IsValid(pname)) { | 9138 if (!validators_->pixel_store.IsValid(pname)) { |
9120 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); | 9139 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); |
9121 return error::kNoError; | 9140 return error::kNoError; |
9122 } | 9141 } |
9123 switch (pname) { | 9142 switch (pname) { |
9124 case GL_PACK_ALIGNMENT: | 9143 case GL_PACK_ALIGNMENT: |
9125 case GL_UNPACK_ALIGNMENT: | 9144 case GL_UNPACK_ALIGNMENT: |
9126 if (!validators_->pixel_store_alignment.IsValid(param)) { | 9145 if (!validators_->pixel_store_alignment.IsValid(param)) { |
9127 LOCAL_SET_GL_ERROR( | 9146 LOCAL_SET_GL_ERROR( |
9128 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE"); | 9147 GL_INVALID_VALUE, "glPixelStorei", "invalid param"); |
9129 return error::kNoError; | 9148 return error::kNoError; |
9130 } | 9149 } |
9131 break; | 9150 break; |
| 9151 case GL_PACK_ROW_LENGTH: |
| 9152 case GL_PACK_SKIP_PIXELS: |
| 9153 case GL_PACK_SKIP_ROWS: |
| 9154 case GL_UNPACK_ROW_LENGTH: |
| 9155 case GL_UNPACK_IMAGE_HEIGHT: |
| 9156 case GL_UNPACK_SKIP_PIXELS: |
| 9157 case GL_UNPACK_SKIP_ROWS: |
| 9158 case GL_UNPACK_SKIP_IMAGES: |
| 9159 if (param < 0) { |
| 9160 LOCAL_SET_GL_ERROR( |
| 9161 GL_INVALID_VALUE, "glPixelStorei", "invalid param"); |
| 9162 return error::kNoError; |
| 9163 } |
9132 default: | 9164 default: |
9133 break; | 9165 break; |
9134 } | 9166 } |
9135 glPixelStorei(pname, param); | 9167 // For pack and unpack parameters (except for alignment), we don't apply them |
| 9168 // if no buffer is bound at PIXEL_PACK or PIXEL_UNPACK. We will handle pack |
| 9169 // and unpack according to the user specified parameters on the client side. |
| 9170 switch (pname) { |
| 9171 case GL_PACK_ROW_LENGTH: |
| 9172 case GL_PACK_SKIP_PIXELS: |
| 9173 case GL_PACK_SKIP_ROWS: |
| 9174 if (state_.bound_pixel_pack_buffer.get()) |
| 9175 glPixelStorei(pname, param); |
| 9176 break; |
| 9177 case GL_UNPACK_ROW_LENGTH: |
| 9178 case GL_UNPACK_IMAGE_HEIGHT: |
| 9179 case GL_UNPACK_SKIP_PIXELS: |
| 9180 case GL_UNPACK_SKIP_ROWS: |
| 9181 case GL_UNPACK_SKIP_IMAGES: |
| 9182 if (state_.bound_pixel_unpack_buffer.get()) |
| 9183 glPixelStorei(pname, param); |
| 9184 break; |
| 9185 default: |
| 9186 glPixelStorei(pname, param); |
| 9187 break; |
| 9188 } |
9136 switch (pname) { | 9189 switch (pname) { |
9137 case GL_PACK_ALIGNMENT: | 9190 case GL_PACK_ALIGNMENT: |
9138 state_.pack_alignment = param; | 9191 state_.pack_alignment = param; |
9139 break; | 9192 break; |
9140 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: | 9193 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: |
9141 state_.pack_reverse_row_order = (param != 0); | 9194 state_.pack_reverse_row_order = (param != 0); |
9142 break; | 9195 break; |
| 9196 case GL_PACK_ROW_LENGTH: |
| 9197 state_.pack_row_length = param; |
| 9198 break; |
| 9199 case GL_PACK_SKIP_PIXELS: |
| 9200 state_.pack_skip_pixels = param; |
| 9201 break; |
| 9202 case GL_PACK_SKIP_ROWS: |
| 9203 state_.pack_skip_rows = param; |
| 9204 break; |
9143 case GL_UNPACK_ALIGNMENT: | 9205 case GL_UNPACK_ALIGNMENT: |
9144 state_.unpack_alignment = param; | 9206 state_.unpack_alignment = param; |
9145 break; | 9207 break; |
| 9208 case GL_UNPACK_ROW_LENGTH: |
| 9209 state_.unpack_row_length = param; |
| 9210 break; |
| 9211 case GL_UNPACK_IMAGE_HEIGHT: |
| 9212 state_.unpack_image_height = param; |
| 9213 break; |
| 9214 case GL_UNPACK_SKIP_PIXELS: |
| 9215 state_.unpack_skip_pixels = param; |
| 9216 break; |
| 9217 case GL_UNPACK_SKIP_ROWS: |
| 9218 state_.unpack_skip_rows = param; |
| 9219 break; |
| 9220 case GL_UNPACK_SKIP_IMAGES: |
| 9221 state_.unpack_skip_images = param; |
| 9222 break; |
9146 default: | 9223 default: |
9147 // Validation should have prevented us from getting here. | 9224 // Validation should have prevented us from getting here. |
9148 NOTREACHED(); | 9225 NOTREACHED(); |
9149 break; | 9226 break; |
9150 } | 9227 } |
9151 return error::kNoError; | 9228 return error::kNoError; |
9152 } | 9229 } |
9153 | 9230 |
9154 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( | 9231 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( |
9155 uint32 immediate_data_size, | 9232 uint32 immediate_data_size, |
9156 const void* cmd_data) { | 9233 const void* cmd_data) { |
9157 const gles2::cmds::PostSubBufferCHROMIUM& c = | 9234 const gles2::cmds::PostSubBufferCHROMIUM& c = |
9158 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data); | 9235 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data); |
9159 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); | 9236 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); |
(...skipping 6169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15329 return error::kNoError; | 15406 return error::kNoError; |
15330 } | 15407 } |
15331 | 15408 |
15332 // Include the auto-generated part of this file. We split this because it means | 15409 // Include the auto-generated part of this file. We split this because it means |
15333 // we can easily edit the non-auto generated parts right here in this file | 15410 // we can easily edit the non-auto generated parts right here in this file |
15334 // instead of having to edit some template or the code generator. | 15411 // instead of having to edit some template or the code generator. |
15335 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 15412 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
15336 | 15413 |
15337 } // namespace gles2 | 15414 } // namespace gles2 |
15338 } // namespace gpu | 15415 } // namespace gpu |
OLD | NEW |