OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
9 | 9 |
10 #include "effects/GrTextureDomainEffect.h" | 10 #include "effects/GrTextureDomainEffect.h" |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 | 1079 |
1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, | 1080 void SkGpuDevice::drawBitmap(const SkDraw& draw, |
1081 const SkBitmap& bitmap, | 1081 const SkBitmap& bitmap, |
1082 const SkMatrix& m, | 1082 const SkMatrix& m, |
1083 const SkPaint& paint) { | 1083 const SkPaint& paint) { |
1084 // We cannot call drawBitmapRect here since 'm' could be anything | 1084 // We cannot call drawBitmapRect here since 'm' could be anything |
1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint, | 1085 this->drawBitmapCommon(draw, bitmap, NULL, m, paint, |
1086 SkCanvas::kNone_DrawBitmapRectFlag); | 1086 SkCanvas::kNone_DrawBitmapRectFlag); |
1087 } | 1087 } |
1088 | 1088 |
| 1089 // This method outsets 'iRect' by 1 all around and then clamps its extents to |
| 1090 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner |
| 1091 // of 'iRect' for all possible outsets/clamps. |
| 1092 static inline void clamped_unit_outset_with_offset(SkIRect* iRect, SkPoint* offs
et, |
| 1093 const SkIRect& clamp) { |
| 1094 iRect->outset(1, 1); |
| 1095 |
| 1096 if (iRect->fLeft < clamp.fLeft) { |
| 1097 iRect->fLeft = clamp.fLeft; |
| 1098 } else { |
| 1099 offset->fX -= SK_Scalar1; |
| 1100 } |
| 1101 if (iRect->fTop < clamp.fTop) { |
| 1102 iRect->fTop = clamp.fTop; |
| 1103 } else { |
| 1104 offset->fY -= SK_Scalar1; |
| 1105 } |
| 1106 |
| 1107 if (iRect->fRight > clamp.fRight) { |
| 1108 iRect->fRight = clamp.fRight; |
| 1109 } |
| 1110 if (iRect->fBottom > clamp.fBottom) { |
| 1111 iRect->fBottom = clamp.fBottom; |
| 1112 } |
| 1113 } |
| 1114 |
1089 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, | 1115 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
1090 const SkBitmap& bitmap, | 1116 const SkBitmap& bitmap, |
1091 const SkRect* srcRectPtr, | 1117 const SkRect* srcRectPtr, |
1092 const SkMatrix& m, | 1118 const SkMatrix& m, |
1093 const SkPaint& paint, | 1119 const SkPaint& paint, |
1094 SkCanvas::DrawBitmapRectFlags flags) { | 1120 SkCanvas::DrawBitmapRectFlags flags) { |
1095 CHECK_SHOULD_DRAW(draw, false); | 1121 CHECK_SHOULD_DRAW(draw, false); |
1096 | 1122 |
1097 SkRect srcRect; | 1123 SkRect srcRect; |
1098 if (NULL == srcRectPtr) { | 1124 if (NULL == srcRectPtr) { |
1099 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); | 1125 srcRect.set(0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.he
ight())); |
1100 } else { | 1126 } else { |
1101 srcRect = *srcRectPtr; | 1127 srcRect = *srcRectPtr; |
1102 } | 1128 } |
1103 | 1129 |
1104 if (paint.getMaskFilter()){ | 1130 if (paint.getMaskFilter()){ |
1105 // TODO: this path needs to be updated to respect the bleed flag | |
1106 | |
1107 // Convert the bitmap to a shader so that the rect can be drawn | 1131 // Convert the bitmap to a shader so that the rect can be drawn |
1108 // through drawRect, which supports mask filters. | 1132 // through drawRect, which supports mask filters. |
1109 SkMatrix newM(m); | 1133 SkMatrix newM(m); |
1110 SkBitmap tmp; // subset of bitmap, if necessary | 1134 SkBitmap tmp; // subset of bitmap, if necessary |
1111 const SkBitmap* bitmapPtr = &bitmap; | 1135 const SkBitmap* bitmapPtr = &bitmap; |
1112 if (NULL != srcRectPtr) { | 1136 if (NULL != srcRectPtr) { |
1113 SkIRect iSrc; | 1137 SkIRect iSrc; |
1114 srcRect.roundOut(&iSrc); | 1138 srcRect.roundOut(&iSrc); |
| 1139 |
| 1140 SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), |
| 1141 SkIntToScalar(iSrc.fTop)); |
| 1142 |
| 1143 if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) { |
| 1144 // In bleed mode we want to expand the src rect on all sides |
| 1145 // but stay within the bitmap bounds |
| 1146 SkIRect iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.heig
ht()); |
| 1147 clamped_unit_outset_with_offset(&iSrc, &offset, iClampRect); |
| 1148 } |
| 1149 |
1115 if (!bitmap.extractSubset(&tmp, iSrc)) { | 1150 if (!bitmap.extractSubset(&tmp, iSrc)) { |
1116 return; // extraction failed | 1151 return; // extraction failed |
1117 } | 1152 } |
1118 bitmapPtr = &tmp; | 1153 bitmapPtr = &tmp; |
1119 srcRect.offset(SkIntToScalar(-iSrc.fLeft), SkIntToScalar(-iSrc.fTop)
); | 1154 srcRect.offset(-offset.fX, -offset.fY); |
1120 // The source rect has changed so update the matrix | 1155 // The source rect has changed so update the matrix |
1121 newM.preTranslate(SkIntToScalar(iSrc.fLeft), SkIntToScalar(iSrc.fTop
)); | 1156 newM.preTranslate(offset.fX, offset.fY); |
1122 } | 1157 } |
1123 | 1158 |
1124 SkPaint paintWithTexture(paint); | 1159 SkPaint paintWithTexture(paint); |
1125 paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr, | 1160 paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr, |
1126 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); | 1161 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); |
1127 | 1162 |
1128 // Transform 'newM' needs to be concatenated to the current matrix, | 1163 // Transform 'newM' needs to be concatenated to the current matrix, |
1129 // rather than transforming the primitive directly, so that 'newM' will | 1164 // rather than transforming the primitive directly, so that 'newM' will |
1130 // also affect the behavior of the mask filter. | 1165 // also affect the behavior of the mask filter. |
1131 SkMatrix drawMatrix; | 1166 SkMatrix drawMatrix; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 params.setFilterMode(textureFilterMode); | 1206 params.setFilterMode(textureFilterMode); |
1172 | 1207 |
1173 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { | 1208 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { |
1174 // take the simple case | 1209 // take the simple case |
1175 this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags); | 1210 this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags); |
1176 } else { | 1211 } else { |
1177 this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags); | 1212 this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags); |
1178 } | 1213 } |
1179 } | 1214 } |
1180 | 1215 |
1181 // This method outsets 'iRect' by 1 all around and then clamps its extents to | |
1182 // 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner | |
1183 // of 'iRect' despite the possible outsets/clamps. | |
1184 static inline void clamped_unit_outset_with_offset(SkIRect* iRect, SkPoint* offs
et, | |
1185 const SkIRect& clamp) { | |
1186 iRect->outset(1, 1); | |
1187 | |
1188 if (iRect->fLeft < clamp.fLeft) { | |
1189 iRect->fLeft = clamp.fLeft; | |
1190 } else { | |
1191 offset->fX -= SK_Scalar1; | |
1192 } | |
1193 if (iRect->fTop < clamp.fTop) { | |
1194 iRect->fTop = clamp.fTop; | |
1195 } else { | |
1196 offset->fY -= SK_Scalar1; | |
1197 } | |
1198 | |
1199 if (iRect->fRight > clamp.fRight) { | |
1200 iRect->fRight = clamp.fRight; | |
1201 } | |
1202 if (iRect->fBottom > clamp.fBottom) { | |
1203 iRect->fBottom = clamp.fBottom; | |
1204 } | |
1205 } | |
1206 | |
1207 // Break 'bitmap' into several tiles to draw it since it has already | 1216 // Break 'bitmap' into several tiles to draw it since it has already |
1208 // been determined to be too large to fit in VRAM | 1217 // been determined to be too large to fit in VRAM |
1209 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, | 1218 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
1210 const SkRect& srcRect, | 1219 const SkRect& srcRect, |
1211 const SkMatrix& m, | 1220 const SkMatrix& m, |
1212 const GrTextureParams& params, | 1221 const GrTextureParams& params, |
1213 const SkPaint& paint, | 1222 const SkPaint& paint, |
1214 SkCanvas::DrawBitmapRectFlags flags) { | 1223 SkCanvas::DrawBitmapRectFlags flags) { |
1215 int maxTextureSize = fContext->getMaxTextureSize(); | 1224 int maxTextureSize = fContext->getMaxTextureSize(); |
1216 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) { | 1225 if (SkPaint::kNone_FilterLevel != paint.getFilterLevel()) { |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 GrTexture* texture, | 1855 GrTexture* texture, |
1847 bool needClear) | 1856 bool needClear) |
1848 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1857 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
1849 | 1858 |
1850 SkASSERT(texture && texture->asRenderTarget()); | 1859 SkASSERT(texture && texture->asRenderTarget()); |
1851 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1860 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
1852 // cache. We pass true for the third argument so that it will get unlocked. | 1861 // cache. We pass true for the third argument so that it will get unlocked. |
1853 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1862 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
1854 fNeedClear = needClear; | 1863 fNeedClear = needClear; |
1855 } | 1864 } |
OLD | NEW |