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

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: update 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
169 } // namespace 181 } // namespace
170 182
171 class GLES2DecoderImpl; 183 class GLES2DecoderImpl;
172 184
173 // Local versions of the SET_GL_ERROR macros 185 // Local versions of the SET_GL_ERROR macros
174 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ 186 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \
175 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) 187 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
176 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ 188 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
177 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ 189 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
178 function_name, value, label) 190 function_name, value, label)
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 void DoLoseContextCHROMIUM(GLenum current, GLenum other); 1039 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
1028 1040
1029 void DoFlushDriverCachesCHROMIUM(void); 1041 void DoFlushDriverCachesCHROMIUM(void);
1030 1042
1031 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, 1043 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
1032 const volatile GLfloat* matrix); 1044 const volatile GLfloat* matrix);
1033 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); 1045 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
1034 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, 1046 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count,
1035 const volatile GLuint* textures); 1047 const volatile GLuint* textures);
1036 1048
1049 void DoFlushMappedBufferRange(
1050 GLenum target, GLintptr offset, GLsizeiptr size);
1051
1037 // Creates a Program for the given program. 1052 // Creates a Program for the given program.
1038 Program* CreateProgram(GLuint client_id, GLuint service_id) { 1053 Program* CreateProgram(GLuint client_id, GLuint service_id) {
1039 return program_manager()->CreateProgram(client_id, service_id); 1054 return program_manager()->CreateProgram(client_id, service_id);
1040 } 1055 }
1041 1056
1042 // Gets the program info for the given program. Returns NULL if none exists. 1057 // Gets the program info for the given program. Returns NULL if none exists.
1043 Program* GetProgram(GLuint client_id) { 1058 Program* GetProgram(GLuint client_id) {
1044 return program_manager()->GetProgram(client_id); 1059 return program_manager()->GetProgram(client_id);
1045 } 1060 }
1046 1061
(...skipping 15777 matching lines...) Expand 10 before | Expand all | Expand 10 after
16824 typedef cmds::MapBufferRange::Result Result; 16839 typedef cmds::MapBufferRange::Result Result;
16825 Result* result = GetSharedMemoryAs<Result*>( 16840 Result* result = GetSharedMemoryAs<Result*>(
16826 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 16841 c.result_shm_id, c.result_shm_offset, sizeof(*result));
16827 if (!result) { 16842 if (!result) {
16828 return error::kOutOfBounds; 16843 return error::kOutOfBounds;
16829 } 16844 }
16830 if (*result != 0) { 16845 if (*result != 0) {
16831 *result = 0; 16846 *result = 0;
16832 return error::kInvalidArguments; 16847 return error::kInvalidArguments;
16833 } 16848 }
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)) { 16849 if (!validators_->buffer_target.IsValid(target)) {
16841 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); 16850 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
16842 return error::kNoError; 16851 return error::kNoError;
16843 } 16852 }
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); 16853 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
16866 if (!buffer) { 16854 if (!buffer) {
16867 LOCAL_SET_GL_ERROR( 16855 LOCAL_SET_GL_ERROR(
16868 GL_INVALID_OPERATION, func_name, "no buffer bound to target"); 16856 GL_INVALID_OPERATION, func_name, "no buffer bound to target");
16869 return error::kNoError; 16857 return error::kNoError;
16870 } 16858 }
16871 if (buffer->GetMappedRange()) { 16859 if (buffer->GetMappedRange()) {
16872 LOCAL_SET_GL_ERROR( 16860 LOCAL_SET_GL_ERROR(
16873 GL_INVALID_OPERATION, func_name, "buffer is already mapped"); 16861 GL_INVALID_OPERATION, func_name, "buffer is already mapped");
16862 return error::kNoError;
16863 }
16864 if (size == 0) {
vmiura 2016/10/04 22:18:52 I think size == 0 should not generate a GL error.
Zhenyao Mo 2016/10/04 22:30:27 This is explicitly required by the spec, ES 3.04,
16865 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "size is zero");
16866 return error::kNoError;
16874 } 16867 }
16875 if (!buffer->CheckRange(offset, size)) { 16868 if (!buffer->CheckRange(offset, size)) {
16876 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range"); 16869 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range");
16877 return error::kNoError; 16870 return error::kNoError;
16878 } 16871 }
16872 int8_t* mem =
16873 GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size);
16874 if (!mem) {
16875 return error::kOutOfBounds;
16876 }
16877 if (!AnyBitsSet(access, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
16878 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16879 "neither MAP_READ_BIT nore MAP_WRITE_BIT is set");
16880 return error::kNoError;
16881 }
vmiura 2016/10/04 22:18:52 Could you add check for "GL_INVALID_VALUE is gener
Zhenyao Mo 2016/10/04 22:30:27 Done.
16882 if (AllBitsSet(access, GL_MAP_READ_BIT) &&
16883 AnyBitsSet(access, (GL_MAP_INVALIDATE_RANGE_BIT |
16884 GL_MAP_INVALIDATE_BUFFER_BIT |
16885 GL_MAP_UNSYNCHRONIZED_BIT))) {
16886 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16887 "Incompatible access bits with MAP_READ_BIT");
16888 return error::kNoError;
16889 }
16890 if (AllBitsSet(access, GL_MAP_FLUSH_EXPLICIT_BIT) &&
16891 !AllBitsSet(access, GL_MAP_WRITE_BIT)) {
16892 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16893 "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT");
16894 return error::kNoError;
16895 }
16896 if (AllBitsSet(access, GL_MAP_INVALIDATE_BUFFER_BIT)) {
16897 // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to
16898 // GL_MAP_INVALIDATE_RANGE_BIT.
16899 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
16900 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
16901 }
16902 // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined
16903 // behaviors.
16904 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
16905 if (AllBitsSet(access, GL_MAP_WRITE_BIT) &&
16906 !AllBitsSet(access, GL_MAP_INVALIDATE_RANGE_BIT)) {
16907 access = (access | GL_MAP_READ_BIT);
16908 }
16879 void* ptr = glMapBufferRange(target, offset, size, access); 16909 void* ptr = glMapBufferRange(target, offset, size, access);
16880 if (ptr == nullptr) { 16910 if (ptr == nullptr) {
16881 return error::kNoError; 16911 return error::kNoError;
16882 } 16912 }
16883 buffer->SetMappedRange(offset, size, access, ptr, 16913 buffer->SetMappedRange(offset, size, access, ptr,
16884 GetSharedMemoryBuffer(data_shm_id), 16914 GetSharedMemoryBuffer(data_shm_id),
16885 static_cast<unsigned int>(data_shm_offset)); 16915 static_cast<unsigned int>(data_shm_offset));
16886 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { 16916 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
16887 memcpy(mem, ptr, size); 16917 memcpy(mem, ptr, size);
16888 } 16918 }
16889 *result = 1; 16919 *result = 1;
16890 return error::kNoError; 16920 return error::kNoError;
16891 } 16921 }
16892 16922
16893 error::Error GLES2DecoderImpl::HandleUnmapBuffer( 16923 error::Error GLES2DecoderImpl::HandleUnmapBuffer(
16894 uint32_t immediate_data_size, 16924 uint32_t immediate_data_size, const volatile void* cmd_data) {
16895 const volatile void* cmd_data) {
16896 if (!unsafe_es3_apis_enabled()) { 16925 if (!unsafe_es3_apis_enabled()) {
16897 return error::kUnknownCommand; 16926 return error::kUnknownCommand;
16898 } 16927 }
16928 const char* func_name = "glUnmapBuffer";
16929
16899 const volatile gles2::cmds::UnmapBuffer& c = 16930 const volatile gles2::cmds::UnmapBuffer& c =
16900 *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data); 16931 *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data);
16901 GLenum target = static_cast<GLenum>(c.target); 16932 GLenum target = static_cast<GLenum>(c.target);
16902 16933
16903 if (!validators_->buffer_target.IsValid(target)) { 16934 if (!validators_->buffer_target.IsValid(target)) {
16904 LOCAL_SET_GL_ERROR_INVALID_ENUM("glMapBufferRange", target, "target"); 16935 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target");
16905 return error::kNoError; 16936 return error::kNoError;
16906 } 16937 }
16907 16938
16908 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); 16939 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
16909 if (!buffer) { 16940 if (!buffer) {
16910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound"); 16941 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound");
16911 return error::kNoError; 16942 return error::kNoError;
16912 } 16943 }
16913 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); 16944 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
16914 if (!mapped_range) { 16945 if (!mapped_range) {
16915 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", 16946 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped");
16916 "buffer is unmapped");
16917 return error::kNoError; 16947 return error::kNoError;
16918 } 16948 }
16919 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 || 16949 if (!AllBitsSet(mapped_range->access, GL_MAP_WRITE_BIT) ||
16920 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) == 16950 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 16951 // If we don't need to write back, or explict flush is required, no copying
16923 // back is needed. 16952 // back is needed.
16924 } else { 16953 } else {
16925 void* mem = mapped_range->GetShmPointer(); 16954 void* mem = mapped_range->GetShmPointer();
16926 if (!mem) { 16955 DCHECK(mem);
16927 return error::kOutOfBounds;
16928 }
16929 DCHECK(mapped_range->pointer); 16956 DCHECK(mapped_range->pointer);
16930 memcpy(mapped_range->pointer, mem, mapped_range->size); 16957 memcpy(mapped_range->pointer, mem, mapped_range->size);
16931 if (buffer->shadowed()) { 16958 if (buffer->shadowed()) {
16932 bool success = buffer->SetRange( 16959 bool success = buffer->SetRange(
16933 mapped_range->offset, mapped_range->size, mem); 16960 mapped_range->offset, mapped_range->size, mem);
16934 DCHECK(success); 16961 DCHECK(success);
16935 } 16962 }
16936 } 16963 }
16937 buffer->RemoveMappedRange(); 16964 buffer->RemoveMappedRange();
16938 GLboolean rt = glUnmapBuffer(target); 16965 GLboolean rt = glUnmapBuffer(target);
16939 if (rt == GL_FALSE) { 16966 if (rt == GL_FALSE) {
16940 // At this point, we have already done the necessary validation, so 16967 // At this point, we have already done the necessary validation, so
16941 // GL_FALSE indicates data corruption. 16968 // GL_FALSE indicates data corruption.
16942 // TODO(zmo): We could redo the map / copy data / unmap to recover, but 16969 // 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 16970 // the second unmap could still return GL_FALSE. For now, we simply lose
16944 // the contexts in the share group. 16971 // the contexts in the share group.
16945 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; 16972 LOG(ERROR) << func_name << " unexpectedly returned GL_FALSE";
16946 // Need to lose current context before broadcasting! 16973 // Need to lose current context before broadcasting!
16947 MarkContextLost(error::kGuilty); 16974 MarkContextLost(error::kGuilty);
16948 group_->LoseContexts(error::kInnocent); 16975 group_->LoseContexts(error::kInnocent);
16949 return error::kLostContext; 16976 return error::kLostContext;
16950 } 16977 }
16951 return error::kNoError; 16978 return error::kNoError;
16952 } 16979 }
16953 16980
16981 void GLES2DecoderImpl::DoFlushMappedBufferRange(
16982 GLenum target, GLintptr offset, GLsizeiptr size) {
16983 const char* func_name = "glFlushMappedBufferRange";
16984 // |size| is validated in HandleFlushMappedBufferRange().
16985 if (offset < 0) {
16986 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "offset < 0");
16987 return;
16988 }
16989 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
16990 if (!buffer) {
16991 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound");
16992 return;
16993 }
16994 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
16995 if (!mapped_range) {
16996 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped");
16997 return;
16998 }
16999 if (!AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) {
17000 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
17001 "buffer is mapped without MAP_FLUSH_EXPLICIT_BIT flag");
17002 return;
17003 }
17004 base::CheckedNumeric<int32_t> range_size = size;
17005 range_size += offset;
17006 if (!range_size.IsValid() ||
17007 range_size.ValueOrDefault(0) > mapped_range->size) {
17008 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name,
17009 "offset + size out of bounds");
17010 return;
17011 }
17012 char* client_data = reinterpret_cast<char*>(mapped_range->GetShmPointer());
17013 DCHECK(client_data);
17014 char* gpu_data = reinterpret_cast<char*>(mapped_range->pointer);
17015 DCHECK(gpu_data);
17016 memcpy(gpu_data + offset, client_data + offset, size);
17017 if (buffer->shadowed()) {
17018 bool success = buffer->SetRange(
17019 mapped_range->offset + offset, size, client_data + offset);
17020 DCHECK(success);
17021 }
17022 glFlushMappedBufferRange(target, offset, size);
17023 }
17024
16954 // Note that GL_LOST_CONTEXT is specific to GLES. 17025 // Note that GL_LOST_CONTEXT is specific to GLES.
16955 // For desktop GL we have to query the reset status proactively. 17026 // For desktop GL we have to query the reset status proactively.
16956 void GLES2DecoderImpl::OnContextLostError() { 17027 void GLES2DecoderImpl::OnContextLostError() {
16957 if (!WasContextLost()) { 17028 if (!WasContextLost()) {
16958 // Need to lose current context before broadcasting! 17029 // Need to lose current context before broadcasting!
16959 CheckResetStatus(); 17030 CheckResetStatus();
16960 group_->LoseContexts(error::kUnknown); 17031 group_->LoseContexts(error::kUnknown);
16961 reset_by_robustness_extension_ = true; 17032 reset_by_robustness_extension_ = true;
16962 } 17033 }
16963 } 17034 }
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after
18144 } 18215 }
18145 18216
18146 // Include the auto-generated part of this file. We split this because it means 18217 // 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 18218 // 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. 18219 // instead of having to edit some template or the code generator.
18149 #include "base/macros.h" 18220 #include "base/macros.h"
18150 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 18221 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
18151 18222
18152 } // namespace gles2 18223 } // namespace gles2
18153 } // namespace gpu 18224 } // 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