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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2221173002: Implementing FlushMappedBufferRange in GPU command buffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: attempt to fix win build Created 4 years, 2 months 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
OLDNEW
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 <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 depth(_depth) {} 159 depth(_depth) {}
160 160
161 int xoffset; 161 int xoffset;
162 int yoffset; 162 int yoffset;
163 int zoffset; 163 int zoffset;
164 int width; 164 int width;
165 int height; 165 int height;
166 int depth; 166 int depth;
167 }; 167 };
168 168
169 // Check if all |ref| bits are set in |bits|.
170 bool AllBitsSet(GLbitfield bits, GLbitfield ref) {
171 DCHECK_NE(0u, ref);
172 return ((bits & ref) == ref);
173 }
174
175 // Check if any of |ref| bits are set in |bits|.
176 bool AnyBitsSet(GLbitfield bits, GLbitfield ref) {
177 DCHECK_NE(0u, ref);
178 return ((bits & ref) != 0);
179 }
180
181 // Check if any bits are set in |bits| other than the bits in |ref|.
182 bool AnyOtherBitsSet(GLbitfield bits, GLbitfield ref) {
183 DCHECK_NE(0u, ref);
184 GLbitfield mask = ~ref;
185 return ((bits & mask) != 0);
186 }
187
169 } // namespace 188 } // namespace
170 189
171 class GLES2DecoderImpl; 190 class GLES2DecoderImpl;
172 191
173 // Local versions of the SET_GL_ERROR macros 192 // Local versions of the SET_GL_ERROR macros
174 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ 193 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \
175 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) 194 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
176 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ 195 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
177 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ 196 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
178 function_name, value, label) 197 function_name, value, label)
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 void DoLoseContextCHROMIUM(GLenum current, GLenum other); 1046 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
1028 1047
1029 void DoFlushDriverCachesCHROMIUM(void); 1048 void DoFlushDriverCachesCHROMIUM(void);
1030 1049
1031 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, 1050 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
1032 const volatile GLfloat* matrix); 1051 const volatile GLfloat* matrix);
1033 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); 1052 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
1034 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, 1053 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count,
1035 const volatile GLuint* textures); 1054 const volatile GLuint* textures);
1036 1055
1056 void DoFlushMappedBufferRange(
1057 GLenum target, GLintptr offset, GLsizeiptr size);
1058
1037 // Creates a Program for the given program. 1059 // Creates a Program for the given program.
1038 Program* CreateProgram(GLuint client_id, GLuint service_id) { 1060 Program* CreateProgram(GLuint client_id, GLuint service_id) {
1039 return program_manager()->CreateProgram(client_id, service_id); 1061 return program_manager()->CreateProgram(client_id, service_id);
1040 } 1062 }
1041 1063
1042 // Gets the program info for the given program. Returns NULL if none exists. 1064 // Gets the program info for the given program. Returns NULL if none exists.
1043 Program* GetProgram(GLuint client_id) { 1065 Program* GetProgram(GLuint client_id) {
1044 return program_manager()->GetProgram(client_id); 1066 return program_manager()->GetProgram(client_id);
1045 } 1067 }
1046 1068
(...skipping 15777 matching lines...) Expand 10 before | Expand all | Expand 10 after
16824 typedef cmds::MapBufferRange::Result Result; 16846 typedef cmds::MapBufferRange::Result Result;
16825 Result* result = GetSharedMemoryAs<Result*>( 16847 Result* result = GetSharedMemoryAs<Result*>(
16826 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 16848 c.result_shm_id, c.result_shm_offset, sizeof(*result));
16827 if (!result) { 16849 if (!result) {
16828 return error::kOutOfBounds; 16850 return error::kOutOfBounds;
16829 } 16851 }
16830 if (*result != 0) { 16852 if (*result != 0) {
16831 *result = 0; 16853 *result = 0;
16832 return error::kInvalidArguments; 16854 return error::kInvalidArguments;
16833 } 16855 }
16834 int8_t* mem =
16835 GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size);
16836 if (!mem) {
16837 return error::kOutOfBounds;
16838 }
16839
16840 if (!validators_->buffer_target.IsValid(target)) { 16856 if (!validators_->buffer_target.IsValid(target)) {
16841 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); 16857 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
16842 return error::kNoError; 16858 return error::kNoError;
16843 } 16859 }
16844
16845 GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT;
16846 if ((access & mask) == mask) {
16847 // TODO(zmo): To be on the safe side, always map
16848 // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT.
16849 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
16850 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
16851 }
16852 // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of
16853 // undefined behaviors.
16854 mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
16855 if ((access & mask) == mask) {
16856 LOCAL_SET_GL_ERROR(
16857 GL_INVALID_OPERATION, func_name, "incompatible access bits");
16858 return error::kNoError;
16859 }
16860 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
16861 if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT &&
16862 (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
16863 access = (access | GL_MAP_READ_BIT);
16864 }
16865 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); 16860 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
16866 if (!buffer) { 16861 if (!buffer) {
16867 LOCAL_SET_GL_ERROR( 16862 LOCAL_SET_GL_ERROR(
16868 GL_INVALID_OPERATION, func_name, "no buffer bound to target"); 16863 GL_INVALID_OPERATION, func_name, "no buffer bound to target");
16869 return error::kNoError; 16864 return error::kNoError;
16870 } 16865 }
16871 if (buffer->GetMappedRange()) { 16866 if (buffer->GetMappedRange()) {
16872 LOCAL_SET_GL_ERROR( 16867 LOCAL_SET_GL_ERROR(
16873 GL_INVALID_OPERATION, func_name, "buffer is already mapped"); 16868 GL_INVALID_OPERATION, func_name, "buffer is already mapped");
16869 return error::kNoError;
16870 }
16871 if (size == 0) {
16872 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "size is zero");
16873 return error::kNoError;
16874 } 16874 }
16875 if (!buffer->CheckRange(offset, size)) { 16875 if (!buffer->CheckRange(offset, size)) {
16876 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range"); 16876 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range");
16877 return error::kNoError; 16877 return error::kNoError;
16878 } 16878 }
16879 int8_t* mem =
16880 GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size);
16881 if (!mem) {
16882 return error::kOutOfBounds;
16883 }
16884 if (AnyOtherBitsSet(access, (GL_MAP_READ_BIT |
16885 GL_MAP_WRITE_BIT |
16886 GL_MAP_INVALIDATE_RANGE_BIT |
16887 GL_MAP_INVALIDATE_BUFFER_BIT |
16888 GL_MAP_FLUSH_EXPLICIT_BIT |
16889 GL_MAP_UNSYNCHRONIZED_BIT))) {
16890 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "invalid access bits");
16891 return error::kNoError;
16892 }
16893 if (!AnyBitsSet(access, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
16894 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16895 "neither MAP_READ_BIT nore MAP_WRITE_BIT is set");
16896 return error::kNoError;
16897 }
16898 if (AllBitsSet(access, GL_MAP_READ_BIT) &&
16899 AnyBitsSet(access, (GL_MAP_INVALIDATE_RANGE_BIT |
16900 GL_MAP_INVALIDATE_BUFFER_BIT |
16901 GL_MAP_UNSYNCHRONIZED_BIT))) {
16902 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16903 "Incompatible access bits with MAP_READ_BIT");
16904 return error::kNoError;
16905 }
16906 if (AllBitsSet(access, GL_MAP_FLUSH_EXPLICIT_BIT) &&
16907 !AllBitsSet(access, GL_MAP_WRITE_BIT)) {
16908 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16909 "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT");
16910 return error::kNoError;
16911 }
16912 if (AllBitsSet(access, GL_MAP_INVALIDATE_BUFFER_BIT)) {
16913 // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to
16914 // GL_MAP_INVALIDATE_RANGE_BIT.
16915 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
16916 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
16917 }
16918 // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined
16919 // behaviors.
16920 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
16921 if (AllBitsSet(access, GL_MAP_WRITE_BIT) &&
16922 !AllBitsSet(access, GL_MAP_INVALIDATE_RANGE_BIT)) {
16923 access = (access | GL_MAP_READ_BIT);
16924 }
16879 void* ptr = glMapBufferRange(target, offset, size, access); 16925 void* ptr = glMapBufferRange(target, offset, size, access);
16880 if (ptr == nullptr) { 16926 if (ptr == nullptr) {
16881 return error::kNoError; 16927 return error::kNoError;
16882 } 16928 }
16883 buffer->SetMappedRange(offset, size, access, ptr, 16929 buffer->SetMappedRange(offset, size, access, ptr,
16884 GetSharedMemoryBuffer(data_shm_id), 16930 GetSharedMemoryBuffer(data_shm_id),
16885 static_cast<unsigned int>(data_shm_offset)); 16931 static_cast<unsigned int>(data_shm_offset));
16886 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { 16932 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
16887 memcpy(mem, ptr, size); 16933 memcpy(mem, ptr, size);
16888 } 16934 }
16889 *result = 1; 16935 *result = 1;
16890 return error::kNoError; 16936 return error::kNoError;
16891 } 16937 }
16892 16938
16893 error::Error GLES2DecoderImpl::HandleUnmapBuffer( 16939 error::Error GLES2DecoderImpl::HandleUnmapBuffer(
16894 uint32_t immediate_data_size, 16940 uint32_t immediate_data_size, const volatile void* cmd_data) {
16895 const volatile void* cmd_data) {
16896 if (!unsafe_es3_apis_enabled()) { 16941 if (!unsafe_es3_apis_enabled()) {
16897 return error::kUnknownCommand; 16942 return error::kUnknownCommand;
16898 } 16943 }
16944 const char* func_name = "glUnmapBuffer";
16945
16899 const volatile gles2::cmds::UnmapBuffer& c = 16946 const volatile gles2::cmds::UnmapBuffer& c =
16900 *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data); 16947 *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data);
16901 GLenum target = static_cast<GLenum>(c.target); 16948 GLenum target = static_cast<GLenum>(c.target);
16902 16949
16903 if (!validators_->buffer_target.IsValid(target)) { 16950 if (!validators_->buffer_target.IsValid(target)) {
16904 LOCAL_SET_GL_ERROR_INVALID_ENUM("glMapBufferRange", target, "target"); 16951 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
16905 return error::kNoError; 16952 return error::kNoError;
16906 } 16953 }
16907 16954
16908 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); 16955 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
16909 if (!buffer) { 16956 if (!buffer) {
16910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound"); 16957 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound");
16911 return error::kNoError; 16958 return error::kNoError;
16912 } 16959 }
16913 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); 16960 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
16914 if (!mapped_range) { 16961 if (!mapped_range) {
16915 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", 16962 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped");
16916 "buffer is unmapped");
16917 return error::kNoError; 16963 return error::kNoError;
16918 } 16964 }
16919 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 || 16965 if (!AllBitsSet(mapped_range->access, GL_MAP_WRITE_BIT) ||
16920 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) == 16966 AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) {
16921 GL_MAP_FLUSH_EXPLICIT_BIT) {
16922 // If we don't need to write back, or explict flush is required, no copying 16967 // If we don't need to write back, or explict flush is required, no copying
16923 // back is needed. 16968 // back is needed.
16924 } else { 16969 } else {
16925 void* mem = mapped_range->GetShmPointer(); 16970 void* mem = mapped_range->GetShmPointer();
16926 if (!mem) { 16971 DCHECK(mem);
16927 return error::kOutOfBounds;
16928 }
16929 DCHECK(mapped_range->pointer); 16972 DCHECK(mapped_range->pointer);
16930 memcpy(mapped_range->pointer, mem, mapped_range->size); 16973 memcpy(mapped_range->pointer, mem, mapped_range->size);
16931 if (buffer->shadowed()) { 16974 if (buffer->shadowed()) {
16932 bool success = buffer->SetRange( 16975 bool success = buffer->SetRange(
16933 mapped_range->offset, mapped_range->size, mem); 16976 mapped_range->offset, mapped_range->size, mem);
16934 DCHECK(success); 16977 DCHECK(success);
16935 } 16978 }
16936 } 16979 }
16937 buffer->RemoveMappedRange(); 16980 buffer->RemoveMappedRange();
16938 GLboolean rt = glUnmapBuffer(target); 16981 GLboolean rt = glUnmapBuffer(target);
16939 if (rt == GL_FALSE) { 16982 if (rt == GL_FALSE) {
16940 // At this point, we have already done the necessary validation, so 16983 // At this point, we have already done the necessary validation, so
16941 // GL_FALSE indicates data corruption. 16984 // GL_FALSE indicates data corruption.
16942 // TODO(zmo): We could redo the map / copy data / unmap to recover, but 16985 // TODO(zmo): We could redo the map / copy data / unmap to recover, but
16943 // the second unmap could still return GL_FALSE. For now, we simply lose 16986 // the second unmap could still return GL_FALSE. For now, we simply lose
16944 // the contexts in the share group. 16987 // the contexts in the share group.
16945 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; 16988 LOG(ERROR) << func_name << " unexpectedly returned GL_FALSE";
16946 // Need to lose current context before broadcasting! 16989 // Need to lose current context before broadcasting!
16947 MarkContextLost(error::kGuilty); 16990 MarkContextLost(error::kGuilty);
16948 group_->LoseContexts(error::kInnocent); 16991 group_->LoseContexts(error::kInnocent);
16949 return error::kLostContext; 16992 return error::kLostContext;
16950 } 16993 }
16951 return error::kNoError; 16994 return error::kNoError;
16952 } 16995 }
16953 16996
16997 void GLES2DecoderImpl::DoFlushMappedBufferRange(
16998 GLenum target, GLintptr offset, GLsizeiptr size) {
16999 const char* func_name = "glFlushMappedBufferRange";
17000 // |size| is validated in HandleFlushMappedBufferRange().
17001 if (offset < 0) {
17002 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "offset < 0");
17003 return;
17004 }
17005 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
17006 if (!buffer) {
17007 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound");
17008 return;
17009 }
17010 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
17011 if (!mapped_range) {
17012 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped");
17013 return;
17014 }
17015 if (!AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) {
17016 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
17017 "buffer is mapped without MAP_FLUSH_EXPLICIT_BIT flag");
17018 return;
17019 }
17020 base::CheckedNumeric<int32_t> range_size = size;
17021 range_size += offset;
17022 if (!range_size.IsValid() ||
17023 range_size.ValueOrDefault(0) > mapped_range->size) {
17024 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
17025 "offset + size out of bounds");
17026 return;
17027 }
17028 char* client_data = reinterpret_cast<char*>(mapped_range->GetShmPointer());
17029 DCHECK(client_data);
17030 char* gpu_data = reinterpret_cast<char*>(mapped_range->pointer);
17031 DCHECK(gpu_data);
17032 memcpy(gpu_data + offset, client_data + offset, size);
17033 if (buffer->shadowed()) {
17034 bool success = buffer->SetRange(
17035 mapped_range->offset + offset, size, client_data + offset);
17036 DCHECK(success);
17037 }
17038 glFlushMappedBufferRange(target, offset, size);
17039 }
17040
16954 // Note that GL_LOST_CONTEXT is specific to GLES. 17041 // Note that GL_LOST_CONTEXT is specific to GLES.
16955 // For desktop GL we have to query the reset status proactively. 17042 // For desktop GL we have to query the reset status proactively.
16956 void GLES2DecoderImpl::OnContextLostError() { 17043 void GLES2DecoderImpl::OnContextLostError() {
16957 if (!WasContextLost()) { 17044 if (!WasContextLost()) {
16958 // Need to lose current context before broadcasting! 17045 // Need to lose current context before broadcasting!
16959 CheckResetStatus(); 17046 CheckResetStatus();
16960 group_->LoseContexts(error::kUnknown); 17047 group_->LoseContexts(error::kUnknown);
16961 reset_by_robustness_extension_ = true; 17048 reset_by_robustness_extension_ = true;
16962 } 17049 }
16963 } 17050 }
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after
18144 } 18231 }
18145 18232
18146 // Include the auto-generated part of this file. We split this because it means 18233 // Include the auto-generated part of this file. We split this because it means
18147 // we can easily edit the non-auto generated parts right here in this file 18234 // we can easily edit the non-auto generated parts right here in this file
18148 // instead of having to edit some template or the code generator. 18235 // instead of having to edit some template or the code generator.
18149 #include "base/macros.h" 18236 #include "base/macros.h"
18150 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 18237 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
18151 18238
18152 } // namespace gles2 18239 } // namespace gles2
18153 } // namespace gpu 18240 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_ids_autogen.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698