| OLD | NEW |
| 1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 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 "cc/output/gl_renderer.h" | 5 #include "cc/output/gl_renderer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <limits> | 11 #include <limits> |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <set> | 13 #include <set> |
| 14 #include <string> | 14 #include <string> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "base/callback_helpers.h" |
| 17 #include "base/feature_list.h" | 18 #include "base/feature_list.h" |
| 18 #include "base/logging.h" | 19 #include "base/logging.h" |
| 19 #include "base/macros.h" | 20 #include "base/macros.h" |
| 20 #include "base/memory/ptr_util.h" | 21 #include "base/memory/ptr_util.h" |
| 21 #include "base/strings/string_split.h" | 22 #include "base/strings/string_split.h" |
| 22 #include "base/strings/string_util.h" | 23 #include "base/strings/string_util.h" |
| 23 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
| 24 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
| 25 #include "base/trace_event/trace_event.h" | 26 #include "base/trace_event/trace_event.h" |
| 26 #include "build/build_config.h" | 27 #include "build/build_config.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } | 146 } |
| 146 } | 147 } |
| 147 | 148 |
| 148 // Smallest unit that impact anti-aliasing output. We use this to | 149 // Smallest unit that impact anti-aliasing output. We use this to |
| 149 // determine when anti-aliasing is unnecessary. | 150 // determine when anti-aliasing is unnecessary. |
| 150 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; | 151 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; |
| 151 | 152 |
| 152 // Block or crash if the number of pending sync queries reach this high as | 153 // Block or crash if the number of pending sync queries reach this high as |
| 153 // something is seriously wrong on the service side if this happens. | 154 // something is seriously wrong on the service side if this happens. |
| 154 const size_t kMaxPendingSyncQueries = 16; | 155 const size_t kMaxPendingSyncQueries = 16; |
| 156 |
| 157 void ReadbackSwappedOverlayTexturesDone( |
| 158 gpu::gles2::GLES2Interface* gl, |
| 159 std::vector<GLuint> buffers, |
| 160 GLuint query, |
| 161 std::vector<SkBitmap>* bitmaps, |
| 162 const base::Callback<void(bool)>& callback) { |
| 163 TRACE_EVENT0("cc", "ReadbackSwappedOverlayTexturesDone"); |
| 164 |
| 165 DCHECK_EQ(buffers.size(), bitmaps->size()); |
| 166 for (size_t i = 0; i < buffers.size(); ++i) { |
| 167 gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, buffers[i]); |
| 168 uint8_t* data = static_cast<uint8_t*>(gl->MapBufferCHROMIUM( |
| 169 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); |
| 170 if (data) |
| 171 memcpy(bitmaps->at(i).getPixels(), data, bitmaps->at(i).getSize()); |
| 172 gl->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); |
| 173 gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
| 174 } |
| 175 gl->DeleteBuffers(buffers.size(), &buffers[0]); |
| 176 gl->DeleteQueriesEXT(1, &query); |
| 177 callback.Run(true); |
| 178 } |
| 179 |
| 155 } // anonymous namespace | 180 } // anonymous namespace |
| 156 | 181 |
| 157 // Parameters needed to draw a RenderPassDrawQuad. | 182 // Parameters needed to draw a RenderPassDrawQuad. |
| 158 struct DrawRenderPassDrawQuadParams { | 183 struct DrawRenderPassDrawQuadParams { |
| 159 DrawRenderPassDrawQuadParams() {} | 184 DrawRenderPassDrawQuadParams() {} |
| 160 ~DrawRenderPassDrawQuadParams() {} | 185 ~DrawRenderPassDrawQuadParams() {} |
| 161 | 186 |
| 162 // Required Inputs. | 187 // Required Inputs. |
| 163 const RenderPassDrawQuad* quad = nullptr; | 188 const RenderPassDrawQuad* quad = nullptr; |
| 164 const Resource* contents_texture = nullptr; | 189 const Resource* contents_texture = nullptr; |
| (...skipping 2762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2927 } | 2952 } |
| 2928 | 2953 |
| 2929 swapping_overlay_resources_.push_back(std::move(pending_overlay_resources_)); | 2954 swapping_overlay_resources_.push_back(std::move(pending_overlay_resources_)); |
| 2930 pending_overlay_resources_.clear(); | 2955 pending_overlay_resources_.clear(); |
| 2931 | 2956 |
| 2932 output_surface_->SwapBuffers(std::move(output_frame)); | 2957 output_surface_->SwapBuffers(std::move(output_frame)); |
| 2933 | 2958 |
| 2934 swap_buffer_rect_ = gfx::Rect(); | 2959 swap_buffer_rect_ = gfx::Rect(); |
| 2935 } | 2960 } |
| 2936 | 2961 |
| 2962 void GLRenderer::ReadbackSwappedOverlayTextures( |
| 2963 std::vector<SkBitmap>* bitmaps, |
| 2964 const base::Callback<void(bool)>& callback) { |
| 2965 TRACE_EVENT0("cc", "GLRenderer::RequestSwappedOverlayTextureSnapshot"); |
| 2966 |
| 2967 if (swapped_and_acked_overlay_resources_.empty()) { |
| 2968 callback.Run(false); |
| 2969 return; |
| 2970 } |
| 2971 |
| 2972 std::vector<GLuint> buffers(swapped_and_acked_overlay_resources_.size()); |
| 2973 gl_->GenBuffers(buffers.size(), &buffers[0]); |
| 2974 |
| 2975 GLuint fbo = 0; |
| 2976 gl_->GenFramebuffers(1, &fbo); |
| 2977 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo); |
| 2978 |
| 2979 GLuint query = 0; |
| 2980 gl_->GenQueriesEXT(1, &query); |
| 2981 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, query); |
| 2982 |
| 2983 DCHECK_EQ(bitmaps->size(), 0u); |
| 2984 for (auto& entry : swapped_and_acked_overlay_resources_) { |
| 2985 const OverlayResourceLock& overlay_resource = entry.second; |
| 2986 gfx::Size size = overlay_resource->size(); |
| 2987 bitmaps->resize(bitmaps->size() + 1); |
| 2988 bitmaps->back().allocN32Pixels(size.width(), size.height()); |
| 2989 std::unique_ptr<ScopedResource> texture = |
| 2990 ScopedResource::Create(resource_provider_); |
| 2991 texture->Allocate(size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888, |
| 2992 gfx::ColorSpace()); |
| 2993 ResourceProvider::ScopedWriteLockGL write_lock(resource_provider_, |
| 2994 texture->id(), false); |
| 2995 gl_->CopyTextureCHROMIUM(overlay_resource->texture_id(), |
| 2996 write_lock.texture_id(), GL_RGBA, GL_UNSIGNED_BYTE, |
| 2997 false, false, false); |
| 2998 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 2999 write_lock.target(), write_lock.texture_id(), 0); |
| 3000 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == |
| 3001 GL_FRAMEBUFFER_COMPLETE); |
| 3002 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 3003 buffers[bitmaps->size() - 1]); |
| 3004 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 3005 bitmaps->back().getSize(), nullptr, GL_STREAM_READ); |
| 3006 gl_->ReadPixels(0, 0, size.width(), size.height(), GL_RGBA, |
| 3007 GL_UNSIGNED_BYTE, nullptr); |
| 3008 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
| 3009 } |
| 3010 |
| 3011 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
| 3012 gl_->DeleteFramebuffers(1, &fbo); |
| 3013 |
| 3014 context_support_->SignalQuery( |
| 3015 query, base::Bind(&ReadbackSwappedOverlayTexturesDone, gl_, |
| 3016 std::move(buffers), query, bitmaps, callback)); |
| 3017 } |
| 3018 |
| 2937 void GLRenderer::SwapBuffersComplete() { | 3019 void GLRenderer::SwapBuffersComplete() { |
| 3020 // If a query is not needed to release the overlay buffers, we can assume |
| 3021 // that once a swap buffer has completed we can release the previously |
| 3022 // swapped buffers. |
| 3023 if (!settings_->release_overlay_resources_after_gpu_query) |
| 3024 swapped_and_acked_overlay_resources_.clear(); |
| 3025 |
| 3026 if (!swapping_overlay_resources_.empty()) { |
| 3027 for (OverlayResourceLock& lock : swapping_overlay_resources_.front()) { |
| 3028 unsigned texture = lock->texture_id(); |
| 3029 if (swapped_and_acked_overlay_resources_.find(texture) == |
| 3030 swapped_and_acked_overlay_resources_.end()) { |
| 3031 swapped_and_acked_overlay_resources_[texture] = std::move(lock); |
| 3032 } |
| 3033 } |
| 3034 swapping_overlay_resources_.pop_front(); |
| 3035 } |
| 3036 |
| 2938 if (settings_->release_overlay_resources_after_gpu_query) { | 3037 if (settings_->release_overlay_resources_after_gpu_query) { |
| 2939 // Once a resource has been swap-ACKed, send a query to the GPU process to | 3038 // Once a resource has been swap-ACKed, send a query to the GPU process to |
| 2940 // ask if the resource is no longer being consumed by the system compositor. | 3039 // ask if the resource is no longer being consumed by the system compositor. |
| 2941 // The response will come with the next swap-ACK. | 3040 // The response will come with the next swap-ACK. |
| 2942 if (!swapping_overlay_resources_.empty()) { | |
| 2943 for (OverlayResourceLock& lock : swapping_overlay_resources_.front()) { | |
| 2944 unsigned texture = lock->texture_id(); | |
| 2945 if (swapped_and_acked_overlay_resources_.find(texture) == | |
| 2946 swapped_and_acked_overlay_resources_.end()) { | |
| 2947 swapped_and_acked_overlay_resources_[texture] = std::move(lock); | |
| 2948 } | |
| 2949 } | |
| 2950 swapping_overlay_resources_.pop_front(); | |
| 2951 } | |
| 2952 | |
| 2953 if (!swapped_and_acked_overlay_resources_.empty()) { | 3041 if (!swapped_and_acked_overlay_resources_.empty()) { |
| 2954 std::vector<unsigned> textures; | 3042 std::vector<unsigned> textures; |
| 2955 textures.reserve(swapped_and_acked_overlay_resources_.size()); | 3043 textures.reserve(swapped_and_acked_overlay_resources_.size()); |
| 2956 for (auto& pair : swapped_and_acked_overlay_resources_) { | 3044 for (auto& pair : swapped_and_acked_overlay_resources_) { |
| 2957 textures.push_back(pair.first); | 3045 textures.push_back(pair.first); |
| 2958 } | 3046 } |
| 2959 gl_->ScheduleCALayerInUseQueryCHROMIUM(textures.size(), textures.data()); | 3047 gl_->ScheduleCALayerInUseQueryCHROMIUM(textures.size(), textures.data()); |
| 2960 } | 3048 } |
| 2961 } else if (swapping_overlay_resources_.size() > 1) { | |
| 2962 // If a query is not needed to release the overlay buffers, we can assume | |
| 2963 // that once a swap buffer has completed we can remove the oldest buffers | |
| 2964 // from the queue. | |
| 2965 swapping_overlay_resources_.pop_front(); | |
| 2966 } | 3049 } |
| 2967 } | 3050 } |
| 2968 | 3051 |
| 2969 void GLRenderer::DidReceiveTextureInUseResponses( | 3052 void GLRenderer::DidReceiveTextureInUseResponses( |
| 2970 const gpu::TextureInUseResponses& responses) { | 3053 const gpu::TextureInUseResponses& responses) { |
| 2971 DCHECK(settings_->release_overlay_resources_after_gpu_query); | 3054 DCHECK(settings_->release_overlay_resources_after_gpu_query); |
| 2972 for (const gpu::TextureInUseResponse& response : responses) { | 3055 for (const gpu::TextureInUseResponse& response : responses) { |
| 2973 if (!response.in_use) { | 3056 if (!response.in_use) { |
| 2974 swapped_and_acked_overlay_resources_.erase(response.texture); | 3057 swapped_and_acked_overlay_resources_.erase(response.texture); |
| 2975 } | 3058 } |
| (...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4045 // The alpha has already been applied when copying the RPDQ to an IOSurface. | 4128 // The alpha has already been applied when copying the RPDQ to an IOSurface. |
| 4046 GLfloat alpha = 1; | 4129 GLfloat alpha = 1; |
| 4047 gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect, | 4130 gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect, |
| 4048 sorting_context_id, gl_transform); | 4131 sorting_context_id, gl_transform); |
| 4049 gl_->ScheduleCALayerCHROMIUM( | 4132 gl_->ScheduleCALayerCHROMIUM( |
| 4050 texture_id, contents_rect, ca_layer_overlay->background_color, | 4133 texture_id, contents_rect, ca_layer_overlay->background_color, |
| 4051 ca_layer_overlay->edge_aa_mask, bounds_rect, filter); | 4134 ca_layer_overlay->edge_aa_mask, bounds_rect, filter); |
| 4052 } | 4135 } |
| 4053 | 4136 |
| 4054 } // namespace cc | 4137 } // namespace cc |
| OLD | NEW |