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 8599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8795 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); | 8800 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); |
8796 } else { | 8801 } else { |
8797 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); | 8802 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); |
8798 } | 8803 } |
8799 if (!data) { | 8804 if (!data) { |
8800 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer", | 8805 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer", |
8801 "Unable to map memory for readback."); | 8806 "Unable to map memory for readback."); |
8802 return; | 8807 return; |
8803 } | 8808 } |
8804 memcpy(pixels, data, pixels_size); | 8809 memcpy(pixels, data, pixels_size); |
8805 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't | |
8806 // have to restore the state. | |
8807 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); | 8810 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); |
8808 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | 8811 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, |
8812 GetServiceId(state_.bound_pixel_pack_buffer.get())); | |
8809 glDeleteBuffersARB(1, &buffer); | 8813 glDeleteBuffersARB(1, &buffer); |
8810 } | 8814 } |
8811 | 8815 |
8812 if (result != NULL) { | 8816 if (result != NULL) { |
8813 *result = true; | 8817 *result = true; |
8814 } | 8818 } |
8815 | 8819 |
8816 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 8820 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
8817 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 8821 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
8818 if ((channels_exist & 0x0008) == 0 && | 8822 if ((channels_exist & 0x0008) == 0 && |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8878 GLsizei height = c.height; | 8882 GLsizei height = c.height; |
8879 GLenum format = c.format; | 8883 GLenum format = c.format; |
8880 GLenum type = c.type; | 8884 GLenum type = c.type; |
8881 GLboolean async = static_cast<GLboolean>(c.async); | 8885 GLboolean async = static_cast<GLboolean>(c.async); |
8882 if (width < 0 || height < 0) { | 8886 if (width < 0 || height < 0) { |
8883 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); | 8887 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); |
8884 return error::kNoError; | 8888 return error::kNoError; |
8885 } | 8889 } |
8886 typedef cmds::ReadPixels::Result Result; | 8890 typedef cmds::ReadPixels::Result Result; |
8887 uint32 pixels_size; | 8891 uint32 pixels_size; |
8892 // TODO(zmo): Need to handle the case of reading into a PIXEL_PACK_BUFFER in | |
8893 // ES3, including more pack parameters. | |
piman
2015/12/01 01:27:33
For safety, because we're not doing range checking
Zhenyao Mo
2015/12/01 22:11:53
Done.
| |
8888 if (!GLES2Util::ComputeImageDataSizes( | 8894 if (!GLES2Util::ComputeImageDataSizes( |
8889 width, height, 1, format, type, state_.pack_alignment, &pixels_size, | 8895 width, height, 1, format, type, state_.pack_alignment, &pixels_size, |
8890 NULL, NULL)) { | 8896 NULL, NULL)) { |
8891 return error::kOutOfBounds; | 8897 return error::kOutOfBounds; |
8892 } | 8898 } |
8893 void* pixels = GetSharedMemoryAs<void*>( | 8899 void* pixels = GetSharedMemoryAs<void*>( |
8894 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); | 8900 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); |
8895 if (!pixels) { | 8901 if (!pixels) { |
8896 return error::kOutOfBounds; | 8902 return error::kOutOfBounds; |
8897 } | 8903 } |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9065 memset(dst, 0, unpadded_row_size); | 9071 memset(dst, 0, unpadded_row_size); |
9066 | 9072 |
9067 // If the row is in range, copy it. | 9073 // If the row is in range, copy it. |
9068 if (ry >= 0 && ry < max_size.height() && read_width > 0) { | 9074 if (ry >= 0 && ry < max_size.height() && read_width > 0) { |
9069 glReadPixels( | 9075 glReadPixels( |
9070 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); | 9076 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); |
9071 } | 9077 } |
9072 dst += padded_row_size; | 9078 dst += padded_row_size; |
9073 } | 9079 } |
9074 } else { | 9080 } else { |
9075 if (async && features().use_async_readpixels) { | 9081 if (async && features().use_async_readpixels && |
9082 !state_.bound_pixel_pack_buffer.get()) { | |
9083 // To simply the state tracking, we don't go down the asyn path if | |
piman
2015/12/01 01:27:33
nit: asyn->async
Zhenyao Mo
2015/12/01 22:11:53
Done.
| |
9084 // a PIXEL_PACK_BUFFER is bound (in which case the client can | |
9085 // implement something similar on their own - all necessary functions | |
9086 // should be exposed). | |
9076 GLuint buffer = 0; | 9087 GLuint buffer = 0; |
9077 glGenBuffersARB(1, &buffer); | 9088 glGenBuffersARB(1, &buffer); |
9078 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); | 9089 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); |
9079 // For ANGLE client version 2, GL_STREAM_READ is not available. | 9090 // For ANGLE client version 2, GL_STREAM_READ is not available. |
9080 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ? | 9091 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ? |
9081 GL_STATIC_DRAW : GL_STREAM_READ; | 9092 GL_STATIC_DRAW : GL_STREAM_READ; |
9082 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); | 9093 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); |
9083 GLenum error = glGetError(); | 9094 GLenum error = glGetError(); |
9084 if (error == GL_NO_ERROR) { | 9095 if (error == GL_NO_ERROR) { |
9096 // No need to worry about ES3 pxiel pack parameters, because no | |
9097 // PIXEL_PACK_BUFFER is bound, and all these settings haven't been | |
9098 // sent to GL. | |
9085 glReadPixels(x, y, width, height, format, type, 0); | 9099 glReadPixels(x, y, width, height, format, type, 0); |
9086 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( | 9100 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( |
9087 new FenceCallback())); | 9101 new FenceCallback())); |
9088 WaitForReadPixels(base::Bind(&GLES2DecoderImpl::FinishReadPixels, | 9102 WaitForReadPixels(base::Bind(&GLES2DecoderImpl::FinishReadPixels, |
9089 base::AsWeakPtr(this), c, buffer)); | 9103 base::AsWeakPtr(this), c, buffer)); |
9090 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | 9104 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
9091 return error::kNoError; | 9105 return error::kNoError; |
9092 } else { | 9106 } else { |
9093 // On error, unbind pack buffer and fall through to sync readpixels | 9107 // On error, unbind pack buffer and fall through to sync readpixels |
9094 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); | 9108 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); |
(...skipping 11 matching lines...) Expand all Loading... | |
9106 } | 9120 } |
9107 | 9121 |
9108 return error::kNoError; | 9122 return error::kNoError; |
9109 } | 9123 } |
9110 | 9124 |
9111 error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, | 9125 error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size, |
9112 const void* cmd_data) { | 9126 const void* cmd_data) { |
9113 const gles2::cmds::PixelStorei& c = | 9127 const gles2::cmds::PixelStorei& c = |
9114 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data); | 9128 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data); |
9115 GLenum pname = c.pname; | 9129 GLenum pname = c.pname; |
9116 GLenum param = c.param; | 9130 GLint param = c.param; |
9117 if (!validators_->pixel_store.IsValid(pname)) { | 9131 if (!validators_->pixel_store.IsValid(pname)) { |
9118 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); | 9132 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); |
9119 return error::kNoError; | 9133 return error::kNoError; |
9120 } | 9134 } |
9121 switch (pname) { | 9135 switch (pname) { |
9122 case GL_PACK_ALIGNMENT: | 9136 case GL_PACK_ALIGNMENT: |
9123 case GL_UNPACK_ALIGNMENT: | 9137 case GL_UNPACK_ALIGNMENT: |
9124 if (!validators_->pixel_store_alignment.IsValid(param)) { | 9138 if (!validators_->pixel_store_alignment.IsValid(param)) { |
9125 LOCAL_SET_GL_ERROR( | 9139 LOCAL_SET_GL_ERROR( |
9126 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE"); | 9140 GL_INVALID_VALUE, "glPixelStorei", "invalid param"); |
9127 return error::kNoError; | 9141 return error::kNoError; |
9128 } | 9142 } |
9129 break; | 9143 break; |
9144 case GL_PACK_ROW_LENGTH: | |
9145 case GL_PACK_SKIP_PIXELS: | |
9146 case GL_PACK_SKIP_ROWS: | |
9147 case GL_UNPACK_ROW_LENGTH: | |
9148 case GL_UNPACK_IMAGE_HEIGHT: | |
9149 case GL_UNPACK_SKIP_PIXELS: | |
9150 case GL_UNPACK_SKIP_ROWS: | |
9151 case GL_UNPACK_SKIP_IMAGES: | |
9152 if (param < 0) { | |
9153 LOCAL_SET_GL_ERROR( | |
9154 GL_INVALID_VALUE, "glPixelStorei", "invalid param"); | |
9155 return error::kNoError; | |
9156 } | |
9130 default: | 9157 default: |
9131 break; | 9158 break; |
9132 } | 9159 } |
9133 glPixelStorei(pname, param); | 9160 // For pack and unpack parameters (except for alignment), we don't apply them |
9161 // if no buffer is bound at PIXEL_PACK or PIXEL_UNPACK. We will handle pack | |
9162 // and unpack according to the user specified parameters on the client side. | |
9163 switch (pname) { | |
9164 case GL_PACK_ROW_LENGTH: | |
9165 case GL_PACK_SKIP_PIXELS: | |
9166 case GL_PACK_SKIP_ROWS: | |
9167 if (state_.bound_pixel_pack_buffer.get()) | |
9168 glPixelStorei(pname, param); | |
9169 break; | |
9170 case GL_UNPACK_ROW_LENGTH: | |
9171 case GL_UNPACK_IMAGE_HEIGHT: | |
9172 case GL_UNPACK_SKIP_PIXELS: | |
9173 case GL_UNPACK_SKIP_ROWS: | |
9174 case GL_UNPACK_SKIP_IMAGES: | |
9175 if (state_.bound_pixel_unpack_buffer.get()) | |
9176 glPixelStorei(pname, param); | |
9177 break; | |
9178 default: | |
9179 glPixelStorei(pname, param); | |
9180 break; | |
9181 } | |
9134 switch (pname) { | 9182 switch (pname) { |
9135 case GL_PACK_ALIGNMENT: | 9183 case GL_PACK_ALIGNMENT: |
9136 state_.pack_alignment = param; | 9184 state_.pack_alignment = param; |
9137 break; | 9185 break; |
9138 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: | 9186 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: |
9139 state_.pack_reverse_row_order = (param != 0); | 9187 state_.pack_reverse_row_order = (param != 0); |
9140 break; | 9188 break; |
9189 case GL_PACK_ROW_LENGTH: | |
9190 state_.pack_row_length = param; | |
9191 break; | |
9192 case GL_PACK_SKIP_PIXELS: | |
9193 state_.pack_skip_pixels = param; | |
9194 break; | |
9195 case GL_PACK_SKIP_ROWS: | |
9196 state_.pack_skip_rows = param; | |
9197 break; | |
9141 case GL_UNPACK_ALIGNMENT: | 9198 case GL_UNPACK_ALIGNMENT: |
9142 state_.unpack_alignment = param; | 9199 state_.unpack_alignment = param; |
9143 break; | 9200 break; |
9201 case GL_UNPACK_ROW_LENGTH: | |
9202 state_.unpack_row_length = param; | |
9203 break; | |
9204 case GL_UNPACK_IMAGE_HEIGHT: | |
9205 state_.unpack_image_height = param; | |
9206 break; | |
9207 case GL_UNPACK_SKIP_PIXELS: | |
9208 state_.unpack_skip_pixels = param; | |
9209 break; | |
9210 case GL_UNPACK_SKIP_ROWS: | |
9211 state_.unpack_skip_rows = param; | |
9212 break; | |
9213 case GL_UNPACK_SKIP_IMAGES: | |
9214 state_.unpack_skip_images = param; | |
9215 break; | |
9144 default: | 9216 default: |
9145 // Validation should have prevented us from getting here. | 9217 // Validation should have prevented us from getting here. |
9146 NOTREACHED(); | 9218 NOTREACHED(); |
9147 break; | 9219 break; |
9148 } | 9220 } |
9149 return error::kNoError; | 9221 return error::kNoError; |
9150 } | 9222 } |
9151 | 9223 |
9152 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( | 9224 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( |
9153 uint32 immediate_data_size, | 9225 uint32 immediate_data_size, |
9154 const void* cmd_data) { | 9226 const void* cmd_data) { |
9155 const gles2::cmds::PostSubBufferCHROMIUM& c = | 9227 const gles2::cmds::PostSubBufferCHROMIUM& c = |
9156 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data); | 9228 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data); |
9157 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); | 9229 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); |
(...skipping 6164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15322 return error::kNoError; | 15394 return error::kNoError; |
15323 } | 15395 } |
15324 | 15396 |
15325 // Include the auto-generated part of this file. We split this because it means | 15397 // Include the auto-generated part of this file. We split this because it means |
15326 // we can easily edit the non-auto generated parts right here in this file | 15398 // we can easily edit the non-auto generated parts right here in this file |
15327 // instead of having to edit some template or the code generator. | 15399 // instead of having to edit some template or the code generator. |
15328 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 15400 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
15329 | 15401 |
15330 } // namespace gles2 | 15402 } // namespace gles2 |
15331 } // namespace gpu | 15403 } // namespace gpu |
OLD | NEW |